@gravity-ui/gateway 4.8.0 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,6 +7,7 @@ A flexible and powerful Express controller for working with REST and gRPC APIs i
7
7
  - [Installation](#installation)
8
8
  - [Basic Usage](#basic-usage)
9
9
  - [Configuration](#configuration)
10
+ - [`proxyHeaders`](#proxyheaders)
10
11
  - [Validation Schema](#validation-schema)
11
12
  - [Using the API in Node.js](#using-the-api-in-nodejs)
12
13
  - [Schema Scopes](#schema-scopes)
@@ -14,13 +15,16 @@ A flexible and powerful Express controller for working with REST and gRPC APIs i
14
15
  - [Overriding Endpoints](#overriding-endpoints)
15
16
  - [Authentication](#authentication)
16
17
  - [Error Handling](#error-handling)
17
- - [gRPC Reflection](#grpc-reflection-for-grpc-actions)
18
18
  - [Retryable Errors](#retryable-errors)
19
+ - [REST-actions](#rest-actions)
20
+ - [gRPC-actions](#grpc-actions)
19
21
  - [Request Cancellation](#request-cancellation)
20
22
  - [Response Content Type Validation](#response-content-type-validation)
23
+ - [gRPC Reflection for gRPC Actions](#grpc-reflection-for-grpc-actions)
21
24
  - [Development](#development)
22
25
  - [Running Tests](#running-tests)
23
26
  - [Contributing](#contributing)
27
+ - [License](#license)
24
28
 
25
29
  ## Installation
26
30
 
@@ -173,10 +177,13 @@ interface GatewayConfig {
173
177
  // List of paths to the necessary proto files for the gateway.
174
178
  includeProtoRoots?: string[];
175
179
 
176
- // Configuration of the path to the certificate in gRPC.
180
+ // Configuration of the path to the CA certificate in gRPC.
177
181
  // Set to null to use system certificates by default.
178
182
  caCertificatePath?: string | null;
179
-
183
+ // Configuration of the path to the client certificate for mTLS in gRPC.
184
+ clientCertificatePath?: string | null;
185
+ // Configuration of the path to the client private key for mTLS in gRPC.
186
+ clientKeyPath?: string | null;
180
187
  // Telemetry sending configuration.
181
188
  sendStats?: SendStats;
182
189
 
@@ -312,6 +319,9 @@ const config = {
312
319
  includeProtoRoots: ['...'],
313
320
  timeout: 25000, // default 25 seconds
314
321
  caCertificatePath: '...',
322
+ // Optional: paths for mTLS client certificate and key
323
+ clientCertificatePath: '...',
324
+ clientKeyPath: '...',
315
325
  };
316
326
 
317
327
  const {api: gatewayApi} = getGatewayControllers({root: Schema}, config);
@@ -19,6 +19,6 @@ export interface GrpcContext {
19
19
  credentials: CredentialsMap;
20
20
  }
21
21
  export declare function createRoot(includeGrpcPaths?: string[]): protobufjs.Root;
22
- export declare function getCredentialsMap(caCertificatePath?: string | null): CredentialsMap;
22
+ export declare function getCredentialsMap(caCertificatePath?: string | null, clientCertificatePath?: string | null, clientKeyPath?: string | null): CredentialsMap;
23
23
  export default function createGrpcAction<Context extends GatewayContext>({ root, credentials }: GrpcContext, endpoints: EndpointsConfig | undefined, config: ApiServiceGrpcActionConfig<Context, any, any>, serviceKey: string, actionName: string, options: GatewayApiOptions<Context>, ErrorConstructor: AppErrorConstructor, serviceSchema?: Pick<BaseSchema[string], 'getAuthHeaders'>): (actionConfig: ApiActionConfig<Context, any, any>) => Promise<import("../models/common").GatewayActionClientStreamResponse<any> | import("../models/common").GatewayActionServerStreamResponse<any> | import("../models/common").GatewayActionDuplexStreamResponse<any> | import("../models/common").GatewayActionUnaryResponse<any>>;
24
24
  export {};
@@ -59,13 +59,21 @@ function createRoot(includeGrpcPaths) {
59
59
  return root;
60
60
  }
61
61
  exports.createRoot = createRoot;
62
- function getCredentialsMap(caCertificatePath) {
62
+ function getCredentialsMap(caCertificatePath, clientCertificatePath, clientKeyPath) {
63
63
  let certificate;
64
+ let clientCertificate;
65
+ let clientKey;
64
66
  if (caCertificatePath && fs_1.default.existsSync(caCertificatePath)) {
65
67
  certificate = fs_1.default.readFileSync(caCertificatePath);
66
68
  }
69
+ if (clientCertificatePath && fs_1.default.existsSync(clientCertificatePath)) {
70
+ clientCertificate = fs_1.default.readFileSync(clientCertificatePath);
71
+ }
72
+ if (clientKeyPath && fs_1.default.existsSync(clientKeyPath)) {
73
+ clientKey = fs_1.default.readFileSync(clientKeyPath);
74
+ }
67
75
  return {
68
- secure: grpc.ChannelCredentials.createSsl(certificate),
76
+ secure: grpc.ChannelCredentials.createSsl(certificate, clientKey, clientCertificate),
69
77
  secureWithoutRootCert: grpc.ChannelCredentials.createSsl(),
70
78
  insecure: grpc.ChannelCredentials.createInsecure(),
71
79
  };
@@ -170,12 +178,37 @@ function clearInstancesCache(service, instancesMap, cachePath, closeTimeout, ctx
170
178
  function getChannelCredential(config, endpointData, credentials) {
171
179
  let endpointInsecure;
172
180
  let endpointSecureWithoutRootCert;
181
+ let endpointCaCertificatePath;
182
+ let endpointClientCertificatePath;
183
+ let endpointClientKeyPath;
173
184
  if ((0, common_2.isExtendedGrpcActionEndpoint)(endpointData)) {
174
185
  endpointInsecure = endpointData === null || endpointData === void 0 ? void 0 : endpointData.insecure;
175
186
  endpointSecureWithoutRootCert = endpointData === null || endpointData === void 0 ? void 0 : endpointData.secureWithoutRootCert;
187
+ endpointCaCertificatePath = endpointData === null || endpointData === void 0 ? void 0 : endpointData.caCertificatePath;
188
+ endpointClientCertificatePath = endpointData === null || endpointData === void 0 ? void 0 : endpointData.clientCertificatePath;
189
+ endpointClientKeyPath = endpointData === null || endpointData === void 0 ? void 0 : endpointData.clientKeyPath;
176
190
  }
177
191
  const isInsecure = config.insecure || endpointInsecure;
178
192
  const isSecureWithoutRootCert = config.secureWithoutRootCert || endpointSecureWithoutRootCert;
193
+ // If endpoint-specific certificates are provided, create new credentials
194
+ if (endpointCaCertificatePath || endpointClientCertificatePath || endpointClientKeyPath) {
195
+ let certificate;
196
+ let clientCertificate;
197
+ let clientKey;
198
+ const caCertPath = endpointCaCertificatePath || config.caCertificatePath;
199
+ const clientCertPath = endpointClientCertificatePath || config.clientCertificatePath;
200
+ const clientKeyPath = endpointClientKeyPath || config.clientKeyPath;
201
+ if (caCertPath && fs_1.default.existsSync(caCertPath)) {
202
+ certificate = fs_1.default.readFileSync(caCertPath);
203
+ }
204
+ if (clientCertPath && fs_1.default.existsSync(clientCertPath)) {
205
+ clientCertificate = fs_1.default.readFileSync(clientCertPath);
206
+ }
207
+ if (clientKeyPath && fs_1.default.existsSync(clientKeyPath)) {
208
+ clientKey = fs_1.default.readFileSync(clientKeyPath);
209
+ }
210
+ return grpc.ChannelCredentials.createSsl(certificate, clientKey, clientCertificate);
211
+ }
179
212
  let creds = credentials.secure;
180
213
  if (isInsecure) {
181
214
  creds = credentials.insecure;
package/build/index.js CHANGED
@@ -259,7 +259,7 @@ function getGatewayControllers(schemasByScope, config) {
259
259
  console.warn('Error when parse GATEWAY_ENDPOINTS_OVERRIDES', err);
260
260
  }
261
261
  }
262
- const credentials = (0, grpc_1.getCredentialsMap)(config.caCertificatePath);
262
+ const credentials = (0, grpc_1.getCredentialsMap)(config.caCertificatePath, config.clientCertificatePath, config.clientKeyPath);
263
263
  for (const scope of (0, common_1.getKeys)(schemasByScope)) {
264
264
  apiByScope[scope] = generateGatewayApi(schemasByScope[scope], config, { root: (0, grpc_1.createRoot)(config.includeProtoRoots), credentials }, apiByScope);
265
265
  }
@@ -118,6 +118,9 @@ export interface ExtendedBaseActionEndpoint {
118
118
  export interface ExtendedGrpcActionEndpoint extends ExtendedBaseActionEndpoint {
119
119
  insecure?: boolean;
120
120
  secureWithoutRootCert?: boolean;
121
+ caCertificatePath?: string;
122
+ clientCertificatePath?: string;
123
+ clientKeyPath?: string;
121
124
  grpcOptions?: object;
122
125
  }
123
126
  export interface ExtendedRestActionEndpoint extends ExtendedBaseActionEndpoint {
@@ -154,6 +157,9 @@ export interface ApiServiceBaseGrpcActionConfig<Context extends GatewayContext,
154
157
  protoKey: string;
155
158
  insecure?: boolean;
156
159
  secureWithoutRootCert?: boolean;
160
+ caCertificatePath?: string;
161
+ clientCertificatePath?: string;
162
+ clientKeyPath?: string;
157
163
  encodedFields?: string[];
158
164
  type?: HandlerType;
159
165
  decodeAnyMessageProtoLoaderOptions?: protobufjs.IConversionOptions;
@@ -274,6 +280,8 @@ export interface GatewayConfig<Context extends GatewayContext, Req extends Gatew
274
280
  sendStats?: SendStats<Context>;
275
281
  includeProtoRoots?: string[];
276
282
  caCertificatePath: string | null;
283
+ clientCertificatePath?: string | null;
284
+ clientKeyPath?: string | null;
277
285
  proxyHeaders: ProxyHeaders;
278
286
  proxyDebugHeaders?: ProxyHeaders;
279
287
  withDebugHeaders?: boolean | ((req: Req, res: Res) => boolean);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/gateway",
3
- "version": "4.8.0",
3
+ "version": "4.9.0",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "main": "build/index.js",