mirror of
https://github.com/BillyOutlast/posthog.git
synced 2026-02-04 03:01:23 +01:00
fix: plugin server temporal certificate handling (#40676)
This commit is contained in:
@@ -48,7 +48,6 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/ua-parser-js": "^0.7.33",
|
||||
"@temporalio/client": "^1.12.0",
|
||||
"@aws-sdk/client-s3": "^3.709.0",
|
||||
"@aws-sdk/lib-storage": "^3.709.0",
|
||||
"@babel/core": "^7.22.10",
|
||||
@@ -59,6 +58,7 @@
|
||||
"@clickhouse/client": "^1.12.0",
|
||||
"@google-cloud/pubsub": "4.11.0",
|
||||
"@google-cloud/storage": "^5.8.5",
|
||||
"@grpc/grpc-js": "^1.14.0",
|
||||
"@maxmind/geoip2-node": "^3.4.0",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
"@opentelemetry/auto-instrumentations-node": "^0.62.1",
|
||||
@@ -74,6 +74,7 @@
|
||||
"@posthog/plugin-scaffold": "1.4.4",
|
||||
"@posthog/siphash": "1.1.1",
|
||||
"@segment/action-destinations": "^3.383.0",
|
||||
"@temporalio/client": "^1.12.0",
|
||||
"@types/lru-cache": "^5.1.0",
|
||||
"@types/node": "^22.13.14",
|
||||
"@types/tail": "^2.2.1",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as grpc from '@grpc/grpc-js'
|
||||
import { Client, Connection } from '@temporalio/client'
|
||||
|
||||
import { Hub } from '~/types'
|
||||
@@ -6,6 +7,8 @@ import { closeHub, createHub } from '~/utils/db/hub'
|
||||
import { TemporalService } from './temporal.service'
|
||||
|
||||
jest.mock('@temporalio/client')
|
||||
jest.mock('@grpc/grpc-js')
|
||||
jest.mock('tls')
|
||||
|
||||
describe('TemporalService', () => {
|
||||
let hub: Hub
|
||||
@@ -34,6 +37,16 @@ describe('TemporalService', () => {
|
||||
},
|
||||
connection: mockConnection,
|
||||
} as any
|
||||
|
||||
// Mock tls.createSecureContext
|
||||
const tls = require('tls')
|
||||
tls.createSecureContext = jest.fn().mockReturnValue({})
|
||||
|
||||
// Mock grpc.credentials.createFromSecureContext
|
||||
const mockCredentials = {}
|
||||
;(grpc.credentials as any) = {
|
||||
createFromSecureContext: jest.fn().mockReturnValue(mockCredentials),
|
||||
}
|
||||
;(Connection.connect as jest.Mock) = jest.fn().mockResolvedValue(mockConnection)
|
||||
;(Client as unknown as jest.Mock) = jest.fn().mockReturnValue(mockClient)
|
||||
|
||||
@@ -60,18 +73,33 @@ describe('TemporalService', () => {
|
||||
hub.TEMPORAL_CLIENT_CERT = 'client-cert'
|
||||
hub.TEMPORAL_CLIENT_KEY = 'client-key'
|
||||
|
||||
const tls = require('tls')
|
||||
const mockSecureContext = {}
|
||||
tls.createSecureContext = jest.fn().mockReturnValue(mockSecureContext)
|
||||
|
||||
const mockCredentials = {}
|
||||
;(grpc.credentials as any) = {
|
||||
createFromSecureContext: jest.fn().mockReturnValue(mockCredentials),
|
||||
}
|
||||
|
||||
const newService = new TemporalService(hub)
|
||||
await newService.startEvaluationRunWorkflow('test', 'test')
|
||||
|
||||
// Verify SecureContext was created with allowPartialTrustChain
|
||||
expect(tls.createSecureContext).toHaveBeenCalledWith({
|
||||
ca: expect.any(Buffer),
|
||||
cert: expect.any(Buffer),
|
||||
key: expect.any(Buffer),
|
||||
allowPartialTrustChain: true,
|
||||
})
|
||||
|
||||
// Verify gRPC credentials were created from SecureContext
|
||||
expect(grpc.credentials.createFromSecureContext).toHaveBeenCalledWith(mockSecureContext)
|
||||
|
||||
// Verify Connection.connect was called with credentials
|
||||
expect(Connection.connect).toHaveBeenCalledWith({
|
||||
address: 'localhost:7233',
|
||||
tls: {
|
||||
serverRootCACertificate: expect.any(Buffer),
|
||||
clientCertPair: {
|
||||
crt: expect.any(Buffer),
|
||||
key: expect.any(Buffer),
|
||||
},
|
||||
},
|
||||
credentials: mockCredentials,
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { Client, Connection, TLSConfig, WorkflowHandle } from '@temporalio/client'
|
||||
import * as grpc from '@grpc/grpc-js'
|
||||
import { Client, Connection, WorkflowHandle } from '@temporalio/client'
|
||||
import { Counter } from 'prom-client'
|
||||
import * as tls from 'tls'
|
||||
|
||||
import { Hub } from '../../types'
|
||||
import { logger } from '../../utils/logger'
|
||||
@@ -35,25 +37,26 @@ export class TemporalService {
|
||||
}
|
||||
|
||||
private async createClient(): Promise<Client> {
|
||||
// Configure TLS if certificates are provided (for production)
|
||||
let tls: TLSConfig | boolean = false
|
||||
if (this.hub.TEMPORAL_CLIENT_ROOT_CA && this.hub.TEMPORAL_CLIENT_CERT && this.hub.TEMPORAL_CLIENT_KEY) {
|
||||
tls = {
|
||||
serverRootCACertificate: Buffer.from(this.hub.TEMPORAL_CLIENT_ROOT_CA),
|
||||
clientCertPair: {
|
||||
crt: Buffer.from(this.hub.TEMPORAL_CLIENT_CERT),
|
||||
key: Buffer.from(this.hub.TEMPORAL_CLIENT_KEY),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const port = this.hub.TEMPORAL_PORT || '7233'
|
||||
const address = `${this.hub.TEMPORAL_HOST}:${port}`
|
||||
|
||||
// Create connection first
|
||||
const connection = await Connection.connect({ address, tls })
|
||||
let credentials: grpc.ChannelCredentials | undefined
|
||||
if (this.hub.TEMPORAL_CLIENT_ROOT_CA && this.hub.TEMPORAL_CLIENT_CERT && this.hub.TEMPORAL_CLIENT_KEY) {
|
||||
const secureContext = tls.createSecureContext({
|
||||
ca: Buffer.from(this.hub.TEMPORAL_CLIENT_ROOT_CA),
|
||||
cert: Buffer.from(this.hub.TEMPORAL_CLIENT_CERT),
|
||||
key: Buffer.from(this.hub.TEMPORAL_CLIENT_KEY),
|
||||
allowPartialTrustChain: true,
|
||||
})
|
||||
|
||||
credentials = grpc.credentials.createFromSecureContext(secureContext)
|
||||
}
|
||||
|
||||
const connection = await Connection.connect({
|
||||
address,
|
||||
...(credentials ? { credentials } : { tls: false }),
|
||||
})
|
||||
|
||||
// Then create client with connection
|
||||
const client = new Client({
|
||||
connection,
|
||||
namespace: this.hub.TEMPORAL_NAMESPACE || 'default',
|
||||
@@ -62,7 +65,7 @@ export class TemporalService {
|
||||
logger.info('✅ Connected to Temporal', {
|
||||
address,
|
||||
namespace: this.hub.TEMPORAL_NAMESPACE,
|
||||
tlsEnabled: tls !== false,
|
||||
tlsEnabled: credentials !== undefined,
|
||||
})
|
||||
|
||||
return client
|
||||
|
||||
45
pnpm-lock.yaml
generated
45
pnpm-lock.yaml
generated
@@ -1220,6 +1220,9 @@ importers:
|
||||
'@google-cloud/storage':
|
||||
specifier: ^5.8.5
|
||||
version: 5.20.5(encoding@0.1.13)
|
||||
'@grpc/grpc-js':
|
||||
specifier: ^1.14.0
|
||||
version: 1.14.0
|
||||
'@maxmind/geoip2-node':
|
||||
specifier: ^3.4.0
|
||||
version: 3.5.0
|
||||
@@ -4826,8 +4829,8 @@ packages:
|
||||
resolution: {integrity: sha512-lOs/dCyveVF8TkVFnFSF7IGd0CJrTm91qiK6JLu+Z8qiT+7Ag0RyVhxZIWkhiACqwABo7kSHDm8FdH8p2wxSSw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
'@grpc/grpc-js@1.13.4':
|
||||
resolution: {integrity: sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==}
|
||||
'@grpc/grpc-js@1.14.0':
|
||||
resolution: {integrity: sha512-N8Jx6PaYzcTRNzirReJCtADVoq4z7+1KQ4E70jTg/koQiMoUSN1kbNjPOqpPbhMFhfU1/l7ixspPl8dNY+FoUg==}
|
||||
engines: {node: '>=12.10.0'}
|
||||
|
||||
'@grpc/proto-loader@0.7.15':
|
||||
@@ -4835,6 +4838,11 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
'@grpc/proto-loader@0.8.0':
|
||||
resolution: {integrity: sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==}
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
'@hapi/hoek@9.3.0':
|
||||
resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==}
|
||||
|
||||
@@ -12304,6 +12312,7 @@ packages:
|
||||
|
||||
expect-playwright@0.8.0:
|
||||
resolution: {integrity: sha512-+kn8561vHAY+dt+0gMqqj1oY+g5xWrsuGMk4QGxotT2WS545nVqqjs37z6hrYfIuucwqthzwJfCJUEYqixyljg==}
|
||||
deprecated: ⚠️ The 'expect-playwright' package is deprecated. The Playwright core assertions (via @playwright/test) now cover the same functionality. Please migrate to built-in expect. See https://playwright.dev/docs/test-assertions for migration.
|
||||
|
||||
expect-type@1.2.2:
|
||||
resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==}
|
||||
@@ -13884,6 +13893,7 @@ packages:
|
||||
|
||||
jest-playwright-preset@4.0.0:
|
||||
resolution: {integrity: sha512-+dGZ1X2KqtwXaabVjTGxy0a3VzYfvYsWaRcuO8vMhyclHSOpGSI1+5cmlqzzCwQ3+fv0EjkTc7I5aV9lo08dYw==}
|
||||
deprecated: ⚠️ The 'jest-playwright-preset' package is deprecated. Please migrate to Playwright's built-in test runner (@playwright/test) which now includes full Jest-style features and parallel testing. See https://playwright.dev/docs/intro for details.
|
||||
peerDependencies:
|
||||
jest: ^29.3.1
|
||||
jest-circus: ^29.3.1
|
||||
@@ -13901,6 +13911,7 @@ packages:
|
||||
|
||||
jest-process-manager@0.4.0:
|
||||
resolution: {integrity: sha512-80Y6snDyb0p8GG83pDxGI/kQzwVTkCxc7ep5FPe/F6JYdvRDhwr6RzRmPSP7SEwuLhxo80lBS/NqOdUIbHIfhw==}
|
||||
deprecated: ⚠️ The 'jest-process-manager' package is deprecated. Please migrate to Playwright's built-in test runner (@playwright/test) which now includes full Jest-style features and parallel testing. See https://playwright.dev/docs/intro for details.
|
||||
|
||||
jest-regex-util@29.6.3:
|
||||
resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==}
|
||||
@@ -14772,6 +14783,7 @@ packages:
|
||||
|
||||
mathjax-full@3.2.2:
|
||||
resolution: {integrity: sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==}
|
||||
deprecated: Version 4 replaces this package with the scoped package @mathjax/src
|
||||
|
||||
mathml-tag-names@2.1.3:
|
||||
resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==}
|
||||
@@ -23214,9 +23226,9 @@ snapshots:
|
||||
- encoding
|
||||
- supports-color
|
||||
|
||||
'@grpc/grpc-js@1.13.4':
|
||||
'@grpc/grpc-js@1.14.0':
|
||||
dependencies:
|
||||
'@grpc/proto-loader': 0.7.15
|
||||
'@grpc/proto-loader': 0.8.0
|
||||
'@js-sdsl/ordered-map': 4.4.2
|
||||
|
||||
'@grpc/proto-loader@0.7.15':
|
||||
@@ -23226,6 +23238,13 @@ snapshots:
|
||||
protobufjs: 7.5.3
|
||||
yargs: 17.7.2
|
||||
|
||||
'@grpc/proto-loader@0.8.0':
|
||||
dependencies:
|
||||
lodash.camelcase: 4.3.0
|
||||
long: 5.2.4
|
||||
protobufjs: 7.5.3
|
||||
yargs: 17.7.2
|
||||
|
||||
'@hapi/hoek@9.3.0': {}
|
||||
|
||||
'@hapi/topo@5.1.0':
|
||||
@@ -24144,7 +24163,7 @@ snapshots:
|
||||
|
||||
'@opentelemetry/exporter-logs-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.13.4
|
||||
'@grpc/grpc-js': 1.14.0
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0)
|
||||
@@ -24174,7 +24193,7 @@ snapshots:
|
||||
|
||||
'@opentelemetry/exporter-metrics-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.13.4
|
||||
'@grpc/grpc-js': 1.14.0
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-metrics-otlp-http': 0.203.0(@opentelemetry/api@1.9.0)
|
||||
@@ -24212,7 +24231,7 @@ snapshots:
|
||||
|
||||
'@opentelemetry/exporter-trace-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.13.4
|
||||
'@grpc/grpc-js': 1.14.0
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0)
|
||||
@@ -24605,7 +24624,7 @@ snapshots:
|
||||
|
||||
'@opentelemetry/otlp-grpc-exporter-base@0.203.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.13.4
|
||||
'@grpc/grpc-js': 1.14.0
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0)
|
||||
@@ -28320,7 +28339,7 @@ snapshots:
|
||||
commander: 9.4.1
|
||||
expect-playwright: 0.8.0
|
||||
glob: 10.4.5
|
||||
jest: 29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
|
||||
jest: 29.7.0(@types/node@22.18.8)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.18.8)(typescript@5.2.2))
|
||||
jest-circus: 29.7.0
|
||||
jest-environment-node: 29.7.0
|
||||
jest-junit: 16.0.0
|
||||
@@ -28618,7 +28637,7 @@ snapshots:
|
||||
|
||||
'@temporalio/client@1.13.1':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.13.4
|
||||
'@grpc/grpc-js': 1.14.0
|
||||
'@temporalio/common': 1.13.1
|
||||
'@temporalio/proto': 1.13.1
|
||||
abort-controller: 3.0.0
|
||||
@@ -33618,7 +33637,7 @@ snapshots:
|
||||
|
||||
google-gax@4.6.1(encoding@0.1.13):
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.13.4
|
||||
'@grpc/grpc-js': 1.14.0
|
||||
'@grpc/proto-loader': 0.7.15
|
||||
'@types/long': 4.0.2
|
||||
abort-controller: 3.0.0
|
||||
@@ -34955,7 +34974,7 @@ snapshots:
|
||||
jest-playwright-preset@4.0.0(jest-circus@29.7.0)(jest-environment-node@29.7.0)(jest-runner@29.7.0)(jest@29.7.0):
|
||||
dependencies:
|
||||
expect-playwright: 0.8.0
|
||||
jest: 29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
|
||||
jest: 29.7.0(@types/node@22.18.8)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.18.8)(typescript@5.2.2))
|
||||
jest-circus: 29.7.0
|
||||
jest-environment-node: 29.7.0
|
||||
jest-process-manager: 0.4.0
|
||||
@@ -35235,7 +35254,7 @@ snapshots:
|
||||
dependencies:
|
||||
ansi-escapes: 6.0.0
|
||||
chalk: 5.4.1
|
||||
jest: 29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
|
||||
jest: 29.7.0(@types/node@22.18.8)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.18.8)(typescript@5.2.2))
|
||||
jest-regex-util: 29.6.3
|
||||
jest-watcher: 29.7.0
|
||||
slash: 5.1.0
|
||||
|
||||
Reference in New Issue
Block a user