mirror of
https://github.com/BillyOutlast/posthog.git
synced 2026-02-04 03:01:23 +01:00
fix: plugin server temporal TLS config (#40718)
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
"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",
|
||||
@@ -58,7 +59,6 @@
|
||||
"@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,7 +74,6 @@
|
||||
"@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,4 +1,3 @@
|
||||
import * as grpc from '@grpc/grpc-js'
|
||||
import { Client, Connection } from '@temporalio/client'
|
||||
|
||||
import { Hub } from '~/types'
|
||||
@@ -7,8 +6,6 @@ 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
|
||||
@@ -37,16 +34,6 @@ 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)
|
||||
|
||||
@@ -73,33 +60,18 @@ 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',
|
||||
credentials: mockCredentials,
|
||||
tls: {
|
||||
serverRootCACertificate: expect.any(Buffer),
|
||||
clientCertPair: {
|
||||
crt: expect.any(Buffer),
|
||||
key: expect.any(Buffer),
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import * as grpc from '@grpc/grpc-js'
|
||||
import { Client, Connection, WorkflowHandle } from '@temporalio/client'
|
||||
import { Client, Connection, TLSConfig, WorkflowHandle } from '@temporalio/client'
|
||||
import fs from 'fs/promises'
|
||||
import { Counter } from 'prom-client'
|
||||
import * as tls from 'tls'
|
||||
|
||||
import { Hub } from '../../types'
|
||||
import { logger } from '../../utils/logger'
|
||||
@@ -36,37 +35,58 @@ export class TemporalService {
|
||||
return this.client
|
||||
}
|
||||
|
||||
private async buildTLSConfig(): Promise<TLSConfig | false> {
|
||||
const { TEMPORAL_CLIENT_ROOT_CA, TEMPORAL_CLIENT_CERT, TEMPORAL_CLIENT_KEY } = this.hub
|
||||
|
||||
if (!(TEMPORAL_CLIENT_ROOT_CA && TEMPORAL_CLIENT_CERT && TEMPORAL_CLIENT_KEY)) {
|
||||
return false
|
||||
}
|
||||
|
||||
let systemCAs = Buffer.alloc(0)
|
||||
try {
|
||||
const fileBuffer = await fs.readFile('/etc/ssl/certs/ca-certificates.crt')
|
||||
systemCAs = Buffer.from(fileBuffer)
|
||||
} catch (err: any) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
logger.warn('⚠️ Failed to load system CA bundle', { err })
|
||||
} else {
|
||||
logger.debug('ℹ️ System CA bundle not found — using only provided root CA')
|
||||
}
|
||||
}
|
||||
|
||||
const combinedCA = Buffer.concat([systemCAs, Buffer.from(TEMPORAL_CLIENT_ROOT_CA)])
|
||||
|
||||
logger.debug('🔐 TLS configuration built', {
|
||||
systemCABundle: systemCAs.length > 0,
|
||||
combinedCABytes: combinedCA.length,
|
||||
})
|
||||
|
||||
return {
|
||||
serverRootCACertificate: combinedCA,
|
||||
clientCertPair: {
|
||||
crt: Buffer.from(TEMPORAL_CLIENT_CERT),
|
||||
key: Buffer.from(TEMPORAL_CLIENT_KEY),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
private async createClient(): Promise<Client> {
|
||||
const tls = await this.buildTLSConfig()
|
||||
|
||||
const port = this.hub.TEMPORAL_PORT || '7233'
|
||||
const address = `${this.hub.TEMPORAL_HOST}:${port}`
|
||||
|
||||
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 }),
|
||||
})
|
||||
const connection = await Connection.connect({ address, tls })
|
||||
|
||||
const client = new Client({
|
||||
connection,
|
||||
namespace: this.hub.TEMPORAL_NAMESPACE || 'default',
|
||||
})
|
||||
|
||||
const tlsEnabled: boolean = credentials !== undefined
|
||||
logger.info('✅ Connected to Temporal', {
|
||||
address,
|
||||
namespace: this.hub.TEMPORAL_NAMESPACE,
|
||||
tlsEnabled,
|
||||
tlsEnabled: tls !== false,
|
||||
})
|
||||
|
||||
return client
|
||||
|
||||
45
pnpm-lock.yaml
generated
45
pnpm-lock.yaml
generated
@@ -1223,9 +1223,6 @@ 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
|
||||
@@ -4869,8 +4866,8 @@ packages:
|
||||
resolution: {integrity: sha512-lOs/dCyveVF8TkVFnFSF7IGd0CJrTm91qiK6JLu+Z8qiT+7Ag0RyVhxZIWkhiACqwABo7kSHDm8FdH8p2wxSSw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
'@grpc/grpc-js@1.14.0':
|
||||
resolution: {integrity: sha512-N8Jx6PaYzcTRNzirReJCtADVoq4z7+1KQ4E70jTg/koQiMoUSN1kbNjPOqpPbhMFhfU1/l7ixspPl8dNY+FoUg==}
|
||||
'@grpc/grpc-js@1.13.4':
|
||||
resolution: {integrity: sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==}
|
||||
engines: {node: '>=12.10.0'}
|
||||
|
||||
'@grpc/proto-loader@0.7.15':
|
||||
@@ -4878,11 +4875,6 @@ 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==}
|
||||
|
||||
@@ -12352,7 +12344,6 @@ 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==}
|
||||
@@ -13933,7 +13924,6 @@ 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
|
||||
@@ -13951,7 +13941,6 @@ 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==}
|
||||
@@ -14823,7 +14812,6 @@ 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==}
|
||||
@@ -23266,9 +23254,9 @@ snapshots:
|
||||
- encoding
|
||||
- supports-color
|
||||
|
||||
'@grpc/grpc-js@1.14.0':
|
||||
'@grpc/grpc-js@1.13.4':
|
||||
dependencies:
|
||||
'@grpc/proto-loader': 0.8.0
|
||||
'@grpc/proto-loader': 0.7.15
|
||||
'@js-sdsl/ordered-map': 4.4.2
|
||||
|
||||
'@grpc/proto-loader@0.7.15':
|
||||
@@ -23278,13 +23266,6 @@ 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':
|
||||
@@ -24203,7 +24184,7 @@ snapshots:
|
||||
|
||||
'@opentelemetry/exporter-logs-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.14.0
|
||||
'@grpc/grpc-js': 1.13.4
|
||||
'@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)
|
||||
@@ -24233,7 +24214,7 @@ snapshots:
|
||||
|
||||
'@opentelemetry/exporter-metrics-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.14.0
|
||||
'@grpc/grpc-js': 1.13.4
|
||||
'@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)
|
||||
@@ -24271,7 +24252,7 @@ snapshots:
|
||||
|
||||
'@opentelemetry/exporter-trace-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.14.0
|
||||
'@grpc/grpc-js': 1.13.4
|
||||
'@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)
|
||||
@@ -24664,7 +24645,7 @@ snapshots:
|
||||
|
||||
'@opentelemetry/otlp-grpc-exporter-base@0.203.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.14.0
|
||||
'@grpc/grpc-js': 1.13.4
|
||||
'@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)
|
||||
@@ -28379,7 +28360,7 @@ snapshots:
|
||||
commander: 9.4.1
|
||||
expect-playwright: 0.8.0
|
||||
glob: 10.4.5
|
||||
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: 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-circus: 29.7.0
|
||||
jest-environment-node: 29.7.0
|
||||
jest-junit: 16.0.0
|
||||
@@ -28677,7 +28658,7 @@ snapshots:
|
||||
|
||||
'@temporalio/client@1.13.1':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.14.0
|
||||
'@grpc/grpc-js': 1.13.4
|
||||
'@temporalio/common': 1.13.1
|
||||
'@temporalio/proto': 1.13.1
|
||||
abort-controller: 3.0.0
|
||||
@@ -33679,7 +33660,7 @@ snapshots:
|
||||
|
||||
google-gax@4.6.1(encoding@0.1.13):
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.14.0
|
||||
'@grpc/grpc-js': 1.13.4
|
||||
'@grpc/proto-loader': 0.7.15
|
||||
'@types/long': 4.0.2
|
||||
abort-controller: 3.0.0
|
||||
@@ -35016,7 +34997,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.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: 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-circus: 29.7.0
|
||||
jest-environment-node: 29.7.0
|
||||
jest-process-manager: 0.4.0
|
||||
@@ -35296,7 +35277,7 @@ snapshots:
|
||||
dependencies:
|
||||
ansi-escapes: 6.0.0
|
||||
chalk: 5.4.1
|
||||
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: 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-regex-util: 29.6.3
|
||||
jest-watcher: 29.7.0
|
||||
slash: 5.1.0
|
||||
|
||||
Reference in New Issue
Block a user