From f4b8d1a4856776e263f54be5d8ba0c5a09850d7a Mon Sep 17 00:00:00 2001 From: jackkav Date: Tue, 24 Sep 2024 13:24:51 +0200 Subject: [PATCH 1/6] wip --- packages/insomnia/src/main/ipc/grpc.ts | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/insomnia/src/main/ipc/grpc.ts b/packages/insomnia/src/main/ipc/grpc.ts index e29bc5ffd5a..50bca4482d6 100644 --- a/packages/insomnia/src/main/ipc/grpc.ts +++ b/packages/insomnia/src/main/ipc/grpc.ts @@ -8,6 +8,7 @@ import { Code, ConnectError, createPromiseClient } from '@connectrpc/connect'; import { createConnectTransport } from '@connectrpc/connect-node'; import { type Call, + ChannelCredentials, type ClientDuplexStream, type ClientReadableStream, credentials, @@ -26,6 +27,7 @@ import type { } from '@grpc/proto-loader'; import * as protoLoader from '@grpc/proto-loader'; import electron, { type IpcMainEvent } from 'electron'; +import fs from 'fs'; import * as grpcReflection from 'grpc-reflection-js'; import { version } from '../../../package.json'; @@ -343,6 +345,24 @@ const isEnumDefinition = (definition: AnyDefinition): definition is EnumTypeDefi return (definition as EnumTypeDefinition).format === 'Protocol Buffer 3 EnumDescriptorProto'; }; +const getChannelCredentialsByWorkspaceId = async (workspaceId: string): ChannelCredentials => { + const clientCerts = await models.clientCertificate.findByParentId(workspaceId); + const caCert = await models.caCertificate.findByParentId(workspaceId); + const caCertficatePath = caCert?.path || null; + const rootCert = (caCertficatePath && fs.readFileSync(caCertficatePath)); + // TODO: filter out disabled client certs and select approriate + const clientCert = clientCerts?.[0]?.cert; + const clientKey = clientCerts?.[0]?.key; + + if (!rootCert) { + return ChannelCredentials.createInsecure(); + } + if (rootCert && clientKey && clientCert) { + return ChannelCredentials.createSsl(rootCert, Buffer.from(clientKey, 'utf8'), Buffer.from(clientCert, 'utf8')); + } + return ChannelCredentials.createSsl(rootCert); +}; + export const start = ( event: IpcMainEvent, { request }: GrpcIpcRequestParams, @@ -355,6 +375,8 @@ export const start = ( const methodType = getMethodType(method); // Create client const { url, enableTls } = parseGrpcUrl(request.url); + const workspaceId = request.parentId; + if (!url) { event.reply('grpc.error', request._id, new Error('URL not specified')); return undefined; @@ -362,7 +384,8 @@ export const start = ( console.log(`[gRPC] connecting to url=${url} ${enableTls ? 'with' : 'without'} TLS`); // @ts-expect-error -- TSCONVERSION second argument should be provided, send an empty string? Needs testing const Client = makeGenericClientConstructor({}); - const client = new Client(url, enableTls ? credentials.createSsl() : credentials.createInsecure()); + const creds = enableTls ? getChannelCredentialsByWorkspaceId(workspaceId) : credentials.createInsecure(); + const client = new Client(url, creds); if (!client) { return; } From 145b83667646f43cab96fb0f098587a7cdd1e337 Mon Sep 17 00:00:00 2001 From: jackkav Date: Tue, 24 Sep 2024 17:32:15 +0200 Subject: [PATCH 2/6] default to tls --- packages/insomnia/src/network/grpc/parse-grpc-url.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/insomnia/src/network/grpc/parse-grpc-url.ts b/packages/insomnia/src/network/grpc/parse-grpc-url.ts index 67765e5b50f..9535a1cb23a 100644 --- a/packages/insomnia/src/network/grpc/parse-grpc-url.ts +++ b/packages/insomnia/src/network/grpc/parse-grpc-url.ts @@ -9,5 +9,5 @@ export const parseGrpcUrl = (grpcUrl: string): { url: string; enableTls: boolean if (lower.startsWith('grpcs://')) { return { url: lower.slice(8), enableTls: true }; } - return { url: lower, enableTls: false }; + return { url: lower, enableTls: true }; }; From c1cab59a3de255bbed7f8053ca9be47da01d6a01 Mon Sep 17 00:00:00 2001 From: jackkav Date: Tue, 24 Sep 2024 17:37:58 +0200 Subject: [PATCH 3/6] pass certs down to grpc --- packages/insomnia/src/main/ipc/grpc.ts | 51 ++++++++++--------- .../ui/components/panes/grpc-request-pane.tsx | 24 ++++++++- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/packages/insomnia/src/main/ipc/grpc.ts b/packages/insomnia/src/main/ipc/grpc.ts index 50bca4482d6..5c38e6f3b1f 100644 --- a/packages/insomnia/src/main/ipc/grpc.ts +++ b/packages/insomnia/src/main/ipc/grpc.ts @@ -11,7 +11,6 @@ import { ChannelCredentials, type ClientDuplexStream, type ClientReadableStream, - credentials, makeGenericClientConstructor, Metadata, type ServiceError, @@ -27,7 +26,6 @@ import type { } from '@grpc/proto-loader'; import * as protoLoader from '@grpc/proto-loader'; import electron, { type IpcMainEvent } from 'electron'; -import fs from 'fs'; import * as grpcReflection from 'grpc-reflection-js'; import { version } from '../../../package.json'; @@ -44,6 +42,9 @@ const grpcCalls = new Map(); export interface GrpcIpcRequestParams { request: RenderedGrpcRequest; + clientCert?: string; + clientKey?: string; + caCertificate?: string; } export interface GrpcIpcMessageParams { @@ -202,16 +203,19 @@ const getMethodsFromReflectionServer = async ( const getMethodsFromReflection = async ( host: string, metadata: GrpcRequestHeader[], - reflectionApi: GrpcRequest['reflectionApi'] + reflectionApi: GrpcRequest['reflectionApi'], + clientCert?: string, + clientKey?: string, + caCertificate?: string, ): Promise => { if (reflectionApi.enabled) { return getMethodsFromReflectionServer(reflectionApi); } try { - const { url, enableTls } = parseGrpcUrl(host); + const { url } = parseGrpcUrl(host); const client = new grpcReflection.Client( url, - enableTls ? credentials.createSsl() : credentials.createInsecure(), + getChannelCredentials({ url: host, caCertificate, clientCert, clientKey }), grpcOptions, filterDisabledMetaData(metadata) ); @@ -265,12 +269,18 @@ export const loadMethodsFromReflection = async (options: { url: string; metadata: GrpcRequestHeader[]; reflectionApi: GrpcRequest['reflectionApi']; + clientCert?: string; + clientKey?: string; + caCertificate?: string; }): Promise => { invariant(options.url, 'gRPC request url not provided'); const methods = await getMethodsFromReflection( options.url, options.metadata, - options.reflectionApi + options.reflectionApi, + options.clientCert, + options.clientKey, + options.caCertificate ); return methods.map(method => ({ type: getMethodType(method), @@ -345,27 +355,22 @@ const isEnumDefinition = (definition: AnyDefinition): definition is EnumTypeDefi return (definition as EnumTypeDefinition).format === 'Protocol Buffer 3 EnumDescriptorProto'; }; -const getChannelCredentialsByWorkspaceId = async (workspaceId: string): ChannelCredentials => { - const clientCerts = await models.clientCertificate.findByParentId(workspaceId); - const caCert = await models.caCertificate.findByParentId(workspaceId); - const caCertficatePath = caCert?.path || null; - const rootCert = (caCertficatePath && fs.readFileSync(caCertficatePath)); - // TODO: filter out disabled client certs and select approriate - const clientCert = clientCerts?.[0]?.cert; - const clientKey = clientCerts?.[0]?.key; - - if (!rootCert) { +const getChannelCredentials = ({ url, clientCert, clientKey, caCertificate }: { url: string; clientCert?: string; clientKey?: string; caCertificate?: string }): ChannelCredentials => { + if (url.toLowerCase().startsWith('grpc:')) { return ChannelCredentials.createInsecure(); } - if (rootCert && clientKey && clientCert) { - return ChannelCredentials.createSsl(rootCert, Buffer.from(clientKey, 'utf8'), Buffer.from(clientCert, 'utf8')); + if (caCertificate && clientKey && clientCert) { + return ChannelCredentials.createSsl(Buffer.from(caCertificate, 'utf8'), Buffer.from(clientKey, 'utf8'), Buffer.from(clientCert, 'utf8')); + } + if (caCertificate) { + return ChannelCredentials.createSsl(Buffer.from(caCertificate, 'utf8'),); } - return ChannelCredentials.createSsl(rootCert); + return ChannelCredentials.createInsecure(); }; export const start = ( event: IpcMainEvent, - { request }: GrpcIpcRequestParams, + { request, clientCert, clientKey, caCertificate }: GrpcIpcRequestParams, ) => { getSelectedMethod(request)?.then(method => { if (!method) { @@ -374,17 +379,15 @@ export const start = ( } const methodType = getMethodType(method); // Create client - const { url, enableTls } = parseGrpcUrl(request.url); - const workspaceId = request.parentId; + const { url } = parseGrpcUrl(request.url); if (!url) { event.reply('grpc.error', request._id, new Error('URL not specified')); return undefined; } - console.log(`[gRPC] connecting to url=${url} ${enableTls ? 'with' : 'without'} TLS`); // @ts-expect-error -- TSCONVERSION second argument should be provided, send an empty string? Needs testing const Client = makeGenericClientConstructor({}); - const creds = enableTls ? getChannelCredentialsByWorkspaceId(workspaceId) : credentials.createInsecure(); + const creds = getChannelCredentials({ url: request.url, clientCert, clientKey, caCertificate }); const client = new Client(url, creds); if (!client) { return; diff --git a/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx b/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx index bfa30a9096b..54e5ff31119 100644 --- a/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx @@ -1,3 +1,4 @@ +import { readFile } from 'fs/promises'; import React, { type FunctionComponent, useRef, useState } from 'react'; import { Tab, TabList, TabPanel, Tabs } from 'react-aria-components'; import { useParams, useRouteLoaderData } from 'react-router-dom'; @@ -11,7 +12,9 @@ import type { GrpcMethodType } from '../../../main/ipc/grpc'; import * as models from '../../../models'; import type { GrpcRequestHeader } from '../../../models/grpc-request'; import { queryAllWorkspaceUrls } from '../../../models/helpers/query-all-workspace-urls'; +import { urlMatchesCertHost } from '../../../network/url-matches-cert-host'; import { tryToInterpolateRequestOrShowRenderErrorModal } from '../../../utils/try-interpolate'; +import { setDefaultProtocol } from '../../../utils/url/protocol'; import { useRequestPatcher } from '../../hooks/use-request'; import { useActiveRequestSyncVCSVersion, useGitVCSVersion } from '../../hooks/use-vcs-version'; import type { GrpcRequestState } from '../../routes/debug'; @@ -98,7 +101,15 @@ export const GrpcRequestPane: FunctionComponent = ({ purpose: 'send', skipBody: canClientStream(methodType), }); - window.main.grpc.start({ request }); + const workspaceClientCertificates = await models.clientCertificate.findByParentId(workspaceId); + const clientCertificate = workspaceClientCertificates.find(c => !c.disabled && urlMatchesCertHost(setDefaultProtocol(c.host, 'grpc:'), request.url, false)); + const caCertificatePath = (await models.caCertificate.findByParentId(workspaceId))?.path; + window.main.grpc.start({ + request, + clientCert: clientCertificate?.cert || undefined, + clientKey: clientCertificate?.key || undefined, + caCertificate: caCertificatePath ? await readFile(caCertificatePath, 'utf8') : undefined, + }); setGrpcState({ ...grpcState, requestMessages: [], @@ -189,7 +200,7 @@ export const GrpcRequestPane: FunctionComponent = ({ disabled={!activeRequest.url} onClick={async () => { try { - const rendered = + let rendered = await tryToInterpolateRequestOrShowRenderErrorModal({ request: activeRequest, environmentId, @@ -199,6 +210,15 @@ export const GrpcRequestPane: FunctionComponent = ({ reflectionApi: activeRequest.reflectionApi, }, }); + const workspaceClientCertificates = await models.clientCertificate.findByParentId(workspaceId); + const clientCertificate = workspaceClientCertificates.find(c => !c.disabled && urlMatchesCertHost(setDefaultProtocol(c.host, 'grpc:'), request.url, false)); + const caCertificatePath = (await models.caCertificate.findByParentId(workspaceId))?.path; + rendered = { + ...rendered, + clientCert: clientCertificate?.cert || undefined, + clientKey: clientCertificate?.key || undefined, + caCertificate: caCertificatePath ? await readFile(caCertificatePath, 'utf8') : undefined, + }; const methods = await window.main.grpc.loadMethodsFromReflection(rendered); setGrpcState({ ...grpcState, methods }); patchRequest(requestId, { protoFileId: '', protoMethodName: '' }); From 593051e6c7ccca9cceda47b97a0a045a4882b20a Mon Sep 17 00:00:00 2001 From: jackkav Date: Tue, 24 Sep 2024 17:59:11 +0200 Subject: [PATCH 4/6] add gRPC tls server --- packages/insomnia-smoke-test/server/grpc.ts | 47 +++++++++++++++++-- .../ui/components/panes/grpc-request-pane.tsx | 8 ++-- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/packages/insomnia-smoke-test/server/grpc.ts b/packages/insomnia-smoke-test/server/grpc.ts index 943d025ec69..94f3c98979e 100644 --- a/packages/insomnia-smoke-test/server/grpc.ts +++ b/packages/insomnia-smoke-test/server/grpc.ts @@ -2,10 +2,11 @@ /* eslint-disable camelcase */ // inspiration: https://github.com/grpc/grpc/blob/master/examples/node/dynamic_codegen/route_guide/route_guide_server.js import * as grpc from '@grpc/grpc-js'; +import { ServerCredentials } from '@grpc/grpc-js'; import { HandleCall } from '@grpc/grpc-js/build/src/server-call'; import * as protoLoader from '@grpc/proto-loader'; import { addReflection } from '@ravanallc/grpc-server-reflection'; -import fs from 'fs'; +import fs, { readFileSync } from 'fs'; import path from 'path'; const PROTO_PATH = path.resolve('../../packages/insomnia/src/network/grpc/__fixtures__/library/route_guide.proto'); @@ -192,8 +193,7 @@ export const startGRPCServer = (port: number) => { const server = new grpc.Server(); // Enable reflection - const descriptorSet = '../../packages/insomnia-smoke-test/fixtures/route_guide.bin'; - addReflection(server, descriptorSet); + addReflection(server, '../../packages/insomnia-smoke-test/fixtures/route_guide.bin'); // @ts-expect-error generated from proto file server.addService(routeguide.RouteGuide.service, { @@ -218,5 +218,46 @@ export const startGRPCServer = (port: number) => { resolve(); }); }); + const serverWithTLS = new grpc.Server(); + + // Enable reflection + addReflection(serverWithTLS, '../../packages/insomnia-smoke-test/fixtures/route_guide.bin'); + + // @ts-expect-error generated from proto file + serverWithTLS.addService(routeguide.RouteGuide.service, { + getFeature: getFeature, + listFeatures: listFeatures, + recordRoute: recordRoute, + routeChat: routeChat, + }); + const rootCert = readFileSync(path.join(__dirname, '../fixtures/certificates/rootCA.pem')); + const serverCert = readFileSync(path.join(__dirname, '../fixtures/certificates/localhost.pem')); + const serverKey = readFileSync(path.join(__dirname, '../fixtures/certificates/localhost-key.pem')); + const serverCredentials = ServerCredentials.createSsl( + rootCert, + [ + { + cert_chain: serverCert, + private_key: serverKey, + }, + ], + true + ); + serverWithTLS.bindAsync('localhost:50052', serverCredentials, error => { + if (error) { + return reject(error); + } + + const dbPath = '../../packages/insomnia/src/network/grpc/__fixtures__/library/route_guide_db.json'; + fs.readFile(path.resolve(dbPath), (err, data) => { + if (err) { + throw err; + } + featureList = JSON.parse(data.toString()); + console.log('Listening at grpcs://localhost:50052 for route_guide.proto'); + serverWithTLS.start(); + resolve(); + }); + }); }); }; diff --git a/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx b/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx index 54e5ff31119..e96f824bc18 100644 --- a/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx @@ -211,12 +211,14 @@ export const GrpcRequestPane: FunctionComponent = ({ }, }); const workspaceClientCertificates = await models.clientCertificate.findByParentId(workspaceId); - const clientCertificate = workspaceClientCertificates.find(c => !c.disabled && urlMatchesCertHost(setDefaultProtocol(c.host, 'grpc:'), request.url, false)); + const clientCertificate = workspaceClientCertificates.find(c => !c.disabled); const caCertificatePath = (await models.caCertificate.findByParentId(workspaceId))?.path; + const clientCert = await readFile(clientCertificate?.cert || '', 'utf8'); + const clientKey = await readFile(clientCertificate?.key || '', 'utf8'); rendered = { ...rendered, - clientCert: clientCertificate?.cert || undefined, - clientKey: clientCertificate?.key || undefined, + clientCert, + clientKey, caCertificate: caCertificatePath ? await readFile(caCertificatePath, 'utf8') : undefined, }; const methods = await window.main.grpc.loadMethodsFromReflection(rendered); From 4670813790198e3850e0bf5e1ad918e10d50e6a2 Mon Sep 17 00:00:00 2001 From: jackkav Date: Fri, 4 Oct 2024 17:35:13 +0200 Subject: [PATCH 5/6] pass down grpc disable ssl validation --- packages/insomnia/src/main/ipc/grpc.ts | 24 ++++++++++++------- .../ui/components/panes/grpc-request-pane.tsx | 6 ++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/insomnia/src/main/ipc/grpc.ts b/packages/insomnia/src/main/ipc/grpc.ts index 5c38e6f3b1f..cadb5d2c541 100644 --- a/packages/insomnia/src/main/ipc/grpc.ts +++ b/packages/insomnia/src/main/ipc/grpc.ts @@ -45,6 +45,7 @@ export interface GrpcIpcRequestParams { clientCert?: string; clientKey?: string; caCertificate?: string; + rejectUnauthorized: boolean; } export interface GrpcIpcMessageParams { @@ -203,6 +204,7 @@ const getMethodsFromReflectionServer = async ( const getMethodsFromReflection = async ( host: string, metadata: GrpcRequestHeader[], + rejectUnauthorized: boolean, reflectionApi: GrpcRequest['reflectionApi'], clientCert?: string, clientKey?: string, @@ -215,7 +217,7 @@ const getMethodsFromReflection = async ( const { url } = parseGrpcUrl(host); const client = new grpcReflection.Client( url, - getChannelCredentials({ url: host, caCertificate, clientCert, clientKey }), + getChannelCredentials({ url: host, caCertificate, clientCert, clientKey, rejectUnauthorized }), grpcOptions, filterDisabledMetaData(metadata) ); @@ -268,6 +270,7 @@ const getMethodsFromReflection = async ( export const loadMethodsFromReflection = async (options: { url: string; metadata: GrpcRequestHeader[]; + rejectUnauthorized: boolean; reflectionApi: GrpcRequest['reflectionApi']; clientCert?: string; clientKey?: string; @@ -277,10 +280,11 @@ export const loadMethodsFromReflection = async (options: { const methods = await getMethodsFromReflection( options.url, options.metadata, + options.rejectUnauthorized, options.reflectionApi, options.clientCert, options.clientKey, - options.caCertificate + options.caCertificate, ); return methods.map(method => ({ type: getMethodType(method), @@ -325,10 +329,12 @@ export const getSelectedMethod = async ( invariant(methods, 'No methods found'); return methods.find(c => c.path === request.protoMethodName); } + const settings = await models.settings.getOrCreate(); const methods = await getMethodsFromReflection( request.url, request.metadata, - request.reflectionApi + settings.validateSSL, + request.reflectionApi, ); invariant(methods, 'No reflection methods found'); return methods.find(c => c.path === request.protoMethodName); @@ -355,22 +361,22 @@ const isEnumDefinition = (definition: AnyDefinition): definition is EnumTypeDefi return (definition as EnumTypeDefinition).format === 'Protocol Buffer 3 EnumDescriptorProto'; }; -const getChannelCredentials = ({ url, clientCert, clientKey, caCertificate }: { url: string; clientCert?: string; clientKey?: string; caCertificate?: string }): ChannelCredentials => { +const getChannelCredentials = ({ url, rejectUnauthorized, clientCert, clientKey, caCertificate }: { url: string; rejectUnauthorized: boolean; clientCert?: string; clientKey?: string; caCertificate?: string }): ChannelCredentials => { if (url.toLowerCase().startsWith('grpc:')) { return ChannelCredentials.createInsecure(); } if (caCertificate && clientKey && clientCert) { - return ChannelCredentials.createSsl(Buffer.from(caCertificate, 'utf8'), Buffer.from(clientKey, 'utf8'), Buffer.from(clientCert, 'utf8')); + return ChannelCredentials.createSsl(Buffer.from(caCertificate, 'utf8'), Buffer.from(clientKey, 'utf8'), Buffer.from(clientCert, 'utf8'), { rejectUnauthorized }); } if (caCertificate) { - return ChannelCredentials.createSsl(Buffer.from(caCertificate, 'utf8'),); + return ChannelCredentials.createSsl(Buffer.from(caCertificate, 'utf8'), null, null, { rejectUnauthorized }); } - return ChannelCredentials.createInsecure(); + return ChannelCredentials.createSsl(null, null, null, { rejectUnauthorized }); }; export const start = ( event: IpcMainEvent, - { request, clientCert, clientKey, caCertificate }: GrpcIpcRequestParams, + { request, rejectUnauthorized, clientCert, clientKey, caCertificate }: GrpcIpcRequestParams, ) => { getSelectedMethod(request)?.then(method => { if (!method) { @@ -387,7 +393,7 @@ export const start = ( } // @ts-expect-error -- TSCONVERSION second argument should be provided, send an empty string? Needs testing const Client = makeGenericClientConstructor({}); - const creds = getChannelCredentials({ url: request.url, clientCert, clientKey, caCertificate }); + const creds = getChannelCredentials({ url: request.url, rejectUnauthorized, clientCert, clientKey, caCertificate }); const client = new Client(url, creds); if (!client) { return; diff --git a/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx b/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx index e96f824bc18..264469ec260 100644 --- a/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx @@ -19,6 +19,7 @@ import { useRequestPatcher } from '../../hooks/use-request'; import { useActiveRequestSyncVCSVersion, useGitVCSVersion } from '../../hooks/use-vcs-version'; import type { GrpcRequestState } from '../../routes/debug'; import type { GrpcRequestLoaderData } from '../../routes/request'; +import { useRootLoaderData } from '../../routes/root'; import type { WorkspaceLoaderData } from '../../routes/workspace'; import { GrpcSendButton } from '../buttons/grpc-send-button'; import { CodeEditor, type CodeEditorHandle } from '../codemirror/code-editor'; @@ -56,7 +57,7 @@ export const GrpcRequestPane: FunctionComponent = ({ reloadRequests, }) => { const { activeRequest } = useRouteLoaderData('request/:requestId') as GrpcRequestLoaderData; - + const { settings } = useRootLoaderData(); const [isProtoModalOpen, setIsProtoModalOpen] = useState(false); const { requestMessages, running, methods } = grpcState; useMount(async () => { @@ -104,8 +105,10 @@ export const GrpcRequestPane: FunctionComponent = ({ const workspaceClientCertificates = await models.clientCertificate.findByParentId(workspaceId); const clientCertificate = workspaceClientCertificates.find(c => !c.disabled && urlMatchesCertHost(setDefaultProtocol(c.host, 'grpc:'), request.url, false)); const caCertificatePath = (await models.caCertificate.findByParentId(workspaceId))?.path; + window.main.grpc.start({ request, + rejectUnauthorized: settings.validateSSL, clientCert: clientCertificate?.cert || undefined, clientKey: clientCertificate?.key || undefined, caCertificate: caCertificatePath ? await readFile(caCertificatePath, 'utf8') : undefined, @@ -217,6 +220,7 @@ export const GrpcRequestPane: FunctionComponent = ({ const clientKey = await readFile(clientCertificate?.key || '', 'utf8'); rendered = { ...rendered, + rejectUnauthorized: settings.validateSSL, clientCert, clientKey, caCertificate: caCertificatePath ? await readFile(caCertificatePath, 'utf8') : undefined, From c3132e94e034992ef3d843a8333ef2b65fecce55 Mon Sep 17 00:00:00 2001 From: jackkav Date: Mon, 7 Oct 2024 12:35:07 +0200 Subject: [PATCH 6/6] fix cert passing --- .../insomnia/src/ui/components/panes/grpc-request-pane.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx b/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx index 264469ec260..b86c65805c9 100644 --- a/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/grpc-request-pane.tsx @@ -105,12 +105,13 @@ export const GrpcRequestPane: FunctionComponent = ({ const workspaceClientCertificates = await models.clientCertificate.findByParentId(workspaceId); const clientCertificate = workspaceClientCertificates.find(c => !c.disabled && urlMatchesCertHost(setDefaultProtocol(c.host, 'grpc:'), request.url, false)); const caCertificatePath = (await models.caCertificate.findByParentId(workspaceId))?.path; - + const clientCert = await readFile(clientCertificate?.cert || '', 'utf8'); + const clientKey = await readFile(clientCertificate?.key || '', 'utf8'); window.main.grpc.start({ request, rejectUnauthorized: settings.validateSSL, - clientCert: clientCertificate?.cert || undefined, - clientKey: clientCertificate?.key || undefined, + clientCert, + clientKey, caCertificate: caCertificatePath ? await readFile(caCertificatePath, 'utf8') : undefined, }); setGrpcState({