diff --git a/api/.env.example b/api/.env.example index 31316e6..84008cd 100644 --- a/api/.env.example +++ b/api/.env.example @@ -10,6 +10,10 @@ DB_PASSWORD=your_secure_password_here # Application Configuration NODE_ENV=development PORT=4000 +# Behind nginx/NPM: bind Apollo to loopback only (hub proxies to 127.0.0.1:4000). +# HOST=127.0.0.1 +# When TLS terminates at the edge, production may run without local cert files. +# TERMINATE_TLS_AT_EDGE=1 # Keycloak Configuration (for Identity Service) KEYCLOAK_URL=http://localhost:8080 diff --git a/api/package.json b/api/package.json index 7be744a..49c9e12 100644 --- a/api/package.json +++ b/api/package.json @@ -24,7 +24,6 @@ "dependencies": { "@apollo/server": "^4.9.5", "@as-integrations/fastify": "^1.1.0", - "@fastify/websocket": "^10.0.1", "@kubernetes/client-node": "^0.20.0", "bcryptjs": "^2.4.3", "dotenv": "^16.3.1", diff --git a/api/pnpm-lock.yaml b/api/pnpm-lock.yaml index 179914a..052d23d 100644 --- a/api/pnpm-lock.yaml +++ b/api/pnpm-lock.yaml @@ -14,9 +14,6 @@ importers: '@as-integrations/fastify': specifier: ^1.1.0 version: 1.3.2(@apollo/server@4.12.2(graphql@16.12.0))(fastify@4.29.1) - '@fastify/websocket': - specifier: ^10.0.1 - version: 10.0.1 '@kubernetes/client-node': specifier: ^0.20.0 version: 0.20.0 @@ -525,9 +522,6 @@ packages: '@fastify/merge-json-schemas@0.1.1': resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==} - '@fastify/websocket@10.0.1': - resolution: {integrity: sha512-8/pQIxTPRD8U94aILTeJ+2O3el/r19+Ej5z1O1mXlqplsUH7KzCjAI0sgd5DM/NoPjAi5qLFNIjgM5+9/rGSNw==} - '@graphql-tools/merge@8.4.2': resolution: {integrity: sha512-XbrHAaj8yDuINph+sAfuq3QCZ/tKblrTLOpirK0+CAgNlZUCHs0Fa+xtMUURgwCVThLle1AF7svJCxFizygLsw==} peerDependencies: @@ -1083,9 +1077,6 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - duplexify@4.1.3: - resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} - ecc-jsbn@0.1.2: resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} @@ -1106,9 +1097,6 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -1978,9 +1966,6 @@ packages: resolution: {integrity: sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==} engines: {node: '>= 0.10.0'} - stream-shift@1.0.3: - resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} - string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -2571,15 +2556,6 @@ snapshots: dependencies: fast-deep-equal: 3.1.3 - '@fastify/websocket@10.0.1': - dependencies: - duplexify: 4.1.3 - fastify-plugin: 4.5.1 - ws: 8.18.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - '@graphql-tools/merge@8.4.2(graphql@16.12.0)': dependencies: '@graphql-tools/utils': 9.2.1(graphql@16.12.0) @@ -3130,13 +3106,6 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - duplexify@4.1.3: - dependencies: - end-of-stream: 1.4.5 - inherits: 2.0.4 - readable-stream: 3.6.2 - stream-shift: 1.0.3 - ecc-jsbn@0.1.2: dependencies: jsbn: 0.1.1 @@ -3154,10 +3123,6 @@ snapshots: encodeurl@2.0.0: {} - end-of-stream@1.4.5: - dependencies: - once: 1.4.0 - es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -4160,8 +4125,6 @@ snapshots: stream-buffers@3.0.3: {} - stream-shift@1.0.3: {} - string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 diff --git a/api/src/lib/tls-config.ts b/api/src/lib/tls-config.ts index a1a5d0d..c831a06 100644 --- a/api/src/lib/tls-config.ts +++ b/api/src/lib/tls-config.ts @@ -39,14 +39,14 @@ export function getTLSConfig(): TLSConfig { // Validate certificate files exist if (!fs.existsSync(certPath)) { - if (process.env.NODE_ENV === 'production') { + if (process.env.NODE_ENV === 'production' && process.env.TERMINATE_TLS_AT_EDGE !== '1') { throw new Error(`TLS certificate not found: ${certPath}`) } logger.warn(`TLS certificate not found: ${certPath} - using HTTP only`) } if (!fs.existsSync(keyPath)) { - if (process.env.NODE_ENV === 'production') { + if (process.env.NODE_ENV === 'production' && process.env.TERMINATE_TLS_AT_EDGE !== '1') { throw new Error(`TLS key not found: ${keyPath}`) } logger.warn(`TLS key not found: ${keyPath} - using HTTP only`) diff --git a/api/src/server.ts b/api/src/server.ts index d61ff4b..3d0a946 100644 --- a/api/src/server.ts +++ b/api/src/server.ts @@ -2,7 +2,6 @@ import 'dotenv/config' import Fastify from 'fastify' import { ApolloServer } from '@apollo/server' import { fastifyApolloDrainPlugin, fastifyApolloHandler } from '@as-integrations/fastify' -import fastifyWebsocket from '@fastify/websocket' import { schema } from './schema' import { createContext } from './context' import { authMiddleware } from './middleware/auth' @@ -94,9 +93,6 @@ async function startServer() { // Initialize blockchain service await initBlockchainService() - - // Register WebSocket support - await fastify.register(fastifyWebsocket) // Start Apollo Server await apolloServer.start() diff --git a/api/src/services/websocket.ts b/api/src/services/websocket.ts index 2b5b9a2..c8fe66e 100644 --- a/api/src/services/websocket.ts +++ b/api/src/services/websocket.ts @@ -13,6 +13,7 @@ export function createWebSocketServer(httpServer: any, path: string) { const wss = new WebSocketServer({ server: httpServer, path, + perMessageDeflate: false, }) const serverCleanup = useServer(