@gravity-ui/gateway 4.7.2 → 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);
@@ -455,17 +465,41 @@ const config = {
455
465
  };
456
466
  ```
457
467
 
458
- You can also define service-specific authentication by adding a `getAuthHeaders` function to individual actions:
468
+ You can define authentication at three levels:
469
+ |
470
+
471
+ 1. **Gateway level** (global) - as shown above
472
+ 2. **Service level** - by adding authentication methods to the service definition
473
+ 3. **Action level** (most specific) - by adding authentication methods to individual actions
474
+ |
475
+ The authentication methods are checked in the following order: action > service > gateway.
476
+ |
477
+ **Service-level authentication:**
478
+ |
459
479
 
460
480
  ```javascript
461
481
  const schema = {
462
482
  userService: {
463
483
  serviceName: 'users',
464
484
  endpoints: {...},
485
+ // Service-level authentication
486
+ getAuthHeaders: (params) => ({
487
+ 'X-User-Service-Auth': params.token,
488
+ }),
489
+ getAuthArgs: (req, res) => ({
490
+ token: req.authorization.token,
491
+ serviceSpecificData: req.headers['x-service-data'],
492
+ }),
465
493
  actions: {
466
494
  getProfile: {
467
495
  path: () => '/profile',
468
496
  method: 'GET',
497
+ // Uses service-level authentication
498
+ },
499
+ updateProfile: {
500
+ path: () => '/profile',
501
+ method: 'PUT',
502
+ // Action-level authentication (overrides service-level)
469
503
  getAuthHeaders: (params) => ({
470
504
  'X-Special-Auth': params.token,
471
505
  }),
@@ -1,7 +1,7 @@
1
1
  import * as grpc from '@grpc/grpc-js';
2
2
  import * as protobufjs from 'protobufjs';
3
3
  import type * as descriptor from 'protobufjs/ext/descriptor';
4
- import { ApiActionConfig, ApiServiceGrpcActionConfig, EndpointsConfig, GatewayApiOptions } from '../models/common';
4
+ import { ApiActionConfig, ApiServiceGrpcActionConfig, BaseSchema, EndpointsConfig, GatewayApiOptions } from '../models/common';
5
5
  import { GatewayContext } from '../models/context';
6
6
  import { AppErrorConstructor } from '../models/error';
7
7
  declare module 'protobufjs' {
@@ -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;
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): (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>>;
22
+ export declare function getCredentialsMap(caCertificatePath?: string | null, clientCertificatePath?: string | null, clientKeyPath?: string | null): CredentialsMap;
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
  };
@@ -86,8 +94,8 @@ function decodeResponse(response, packageRoot, ctx, encodedFields = [], ErrorCon
86
94
  }
87
95
  });
88
96
  }
89
- function createMetadata({ options, actionConfig, config, params, serviceName, proxyHeadersCaller, ctx, }) {
90
- var _a;
97
+ function createMetadata({ options, actionConfig, config, params, serviceName, proxyHeadersCaller, ctx, serviceSchema, }) {
98
+ var _a, _b;
91
99
  const { headers, requestId, authArgs } = actionConfig;
92
100
  const proxyHeaders = [...constants_1.DEFAULT_PROXY_HEADERS];
93
101
  let metadata = {
@@ -111,7 +119,7 @@ function createMetadata({ options, actionConfig, config, params, serviceName, pr
111
119
  metadata[headerName] = headers[headerName];
112
120
  }
113
121
  }
114
- const authHeaders = ((_a = config.getAuthHeaders) !== null && _a !== void 0 ? _a : options.getAuthHeaders)({
122
+ const authHeaders = ((_b = (_a = config.getAuthHeaders) !== null && _a !== void 0 ? _a : serviceSchema === null || serviceSchema === void 0 ? void 0 : serviceSchema.getAuthHeaders) !== null && _b !== void 0 ? _b : options.getAuthHeaders)({
115
123
  actionType: 'grpc',
116
124
  serviceName,
117
125
  requestHeaders: headers,
@@ -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;
@@ -333,7 +366,7 @@ function createServiceOptions(timeout) {
333
366
  deadline: Date.now() + timeout,
334
367
  };
335
368
  }
336
- function createGrpcAction({ root, credentials }, endpoints, config, serviceKey, actionName, options, ErrorConstructor) {
369
+ function createGrpcAction({ root, credentials }, endpoints, config, serviceKey, actionName, options, ErrorConstructor, serviceSchema) {
337
370
  const serviceName = (options === null || options === void 0 ? void 0 : options.serviceName) || serviceKey;
338
371
  let getService;
339
372
  let recreateService;
@@ -520,6 +553,7 @@ function createGrpcAction({ root, credentials }, endpoints, config, serviceKey,
520
553
  serviceName,
521
554
  proxyHeadersCaller,
522
555
  ctx,
556
+ serviceSchema,
523
557
  });
524
558
  if (!service[action]) {
525
559
  reject(new parse_error_1.GrpcError('Not found action', {
@@ -1,7 +1,7 @@
1
- import { ApiActionConfig, ApiServiceRestActionConfig, EndpointsConfig, GatewayApiOptions, Headers } from '../models/common';
1
+ import { ApiActionConfig, ApiServiceRestActionConfig, BaseSchema, EndpointsConfig, GatewayApiOptions, Headers } from '../models/common';
2
2
  import { GatewayContext } from '../models/context';
3
3
  import { AppErrorConstructor } from '../models/error';
4
- export default function createRestAction<Context extends GatewayContext>(endpoints: EndpointsConfig | undefined, config: ApiServiceRestActionConfig<Context, any, any>, serviceKey: string, actionName: string, options: GatewayApiOptions<Context>, ErrorConstructor: AppErrorConstructor): (actionConfig: ApiActionConfig<Context, any>) => Promise<{
4
+ export default function createRestAction<Context extends GatewayContext>(endpoints: EndpointsConfig | undefined, config: ApiServiceRestActionConfig<Context, any, any>, serviceKey: string, actionName: string, options: GatewayApiOptions<Context>, ErrorConstructor: AppErrorConstructor, serviceSchema?: Pick<BaseSchema[string], 'getAuthHeaders'>): (actionConfig: ApiActionConfig<Context, any>) => Promise<{
5
5
  responseData: unknown;
6
6
  responseHeaders?: Headers | undefined;
7
7
  debugHeaders: Headers;
@@ -33,13 +33,13 @@ function getConfigSerializerFunction(config) {
33
33
  }
34
34
  return undefined;
35
35
  }
36
- function createRestAction(endpoints, config, serviceKey, actionName, options, ErrorConstructor) {
36
+ function createRestAction(endpoints, config, serviceKey, actionName, options, ErrorConstructor, serviceSchema) {
37
37
  var _a, _b, _c, _d;
38
38
  const timeout = (_c = (_a = config === null || config === void 0 ? void 0 : config.timeout) !== null && _a !== void 0 ? _a : (_b = options === null || options === void 0 ? void 0 : options.axiosConfig) === null || _b === void 0 ? void 0 : _b.timeout) !== null && _c !== void 0 ? _c : options === null || options === void 0 ? void 0 : options.timeout;
39
39
  const defaultAxiosClient = (0, axios_1.getAxiosClient)(timeout, config === null || config === void 0 ? void 0 : config.retries, (_d = config === null || config === void 0 ? void 0 : config.axiosRetryCondition) !== null && _d !== void 0 ? _d : options === null || options === void 0 ? void 0 : options.axiosRetryCondition, options === null || options === void 0 ? void 0 : options.axiosConfig, options === null || options === void 0 ? void 0 : options.axiosInterceptors);
40
40
  /* eslint-disable complexity */
41
41
  return async function action(actionConfig) {
42
- var _a, _b, _c, _d, _e, _f, _g, _h;
42
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
43
43
  const { args, requestId, headers: requestHeaders, ctx: parentCtx, authArgs, userId, abortSignal, } = actionConfig;
44
44
  const debugHeaders = {};
45
45
  const lang = requestHeaders[constants_1.DEFAULT_LANG_HEADER] || constants_1.Lang.Ru; // header might be empty string
@@ -142,7 +142,7 @@ function createRestAction(endpoints, config, serviceKey, actionName, options, Er
142
142
  if (idempotency) {
143
143
  actionHeaders['idempotency-key'] = requestHeaders['idempotency-key'] || (0, uuid_1.v4)();
144
144
  }
145
- const authHeaders = ((_b = config.getAuthHeaders) !== null && _b !== void 0 ? _b : options.getAuthHeaders)({
145
+ const authHeaders = ((_c = (_b = config.getAuthHeaders) !== null && _b !== void 0 ? _b : serviceSchema === null || serviceSchema === void 0 ? void 0 : serviceSchema.getAuthHeaders) !== null && _c !== void 0 ? _c : options.getAuthHeaders)({
146
146
  actionType: 'rest',
147
147
  serviceName,
148
148
  requestHeaders,
@@ -202,7 +202,7 @@ function createRestAction(endpoints, config, serviceKey, actionName, options, Er
202
202
  }
203
203
  const startRequestTime = Date.now();
204
204
  let axiosClient = defaultAxiosClient;
205
- const customActionTimeout = (_e = (_d = (_c = actionConfig.timeout) !== null && _c !== void 0 ? _c : config.timeout) !== null && _d !== void 0 ? _d : endpointAxiosConfig === null || endpointAxiosConfig === void 0 ? void 0 : endpointAxiosConfig.timeout) !== null && _e !== void 0 ? _e : timeout;
205
+ const customActionTimeout = (_f = (_e = (_d = actionConfig.timeout) !== null && _d !== void 0 ? _d : config.timeout) !== null && _e !== void 0 ? _e : endpointAxiosConfig === null || endpointAxiosConfig === void 0 ? void 0 : endpointAxiosConfig.timeout) !== null && _f !== void 0 ? _f : timeout;
206
206
  if (actionConfig.timeout || endpointAxiosConfig) {
207
207
  const customActionAxiosConfig = Object.assign(Object.assign({}, ((options === null || options === void 0 ? void 0 : options.axiosConfig) || {})), (endpointAxiosConfig || {}));
208
208
  axiosClient = (0, axios_1.getAxiosClient)(customActionTimeout, config === null || config === void 0 ? void 0 : config.retries, options.axiosRetryCondition, customActionAxiosConfig, options === null || options === void 0 ? void 0 : options.axiosInterceptors);
@@ -216,7 +216,7 @@ function createRestAction(endpoints, config, serviceKey, actionName, options, Er
216
216
  requestId,
217
217
  requestMethod: config.method,
218
218
  requestUrl: actionURL,
219
- traceId: ((_f = ctx.getTraceId) === null || _f === void 0 ? void 0 : _f.call(ctx)) || '',
219
+ traceId: ((_g = ctx.getTraceId) === null || _g === void 0 ? void 0 : _g.call(ctx)) || '',
220
220
  userId: userId || '',
221
221
  };
222
222
  const requestConfig = {
@@ -243,7 +243,7 @@ function createRestAction(endpoints, config, serviceKey, actionName, options, Er
243
243
  const responseHeaders = {};
244
244
  const endRequestTime = Date.now();
245
245
  requestData.requestTime = endRequestTime - startRequestTime;
246
- const actualResponseContentType = (_g = response.headers) === null || _g === void 0 ? void 0 : _g['Content-Type'];
246
+ const actualResponseContentType = (_h = response.headers) === null || _h === void 0 ? void 0 : _h['Content-Type'];
247
247
  const expectedResponseContentType = config.expectedResponseContentType || options.expectedResponseContentType;
248
248
  if (actualResponseContentType && expectedResponseContentType) {
249
249
  let isInvalidResponseContentType;
@@ -340,7 +340,7 @@ function createRestAction(endpoints, config, serviceKey, actionName, options, Er
340
340
  }
341
341
  const responseStatus = lodash_1.default.get(parsedError, 'status') || lodash_1.default.get(error, 'status', 500);
342
342
  if (options === null || options === void 0 ? void 0 : options.sendStats) {
343
- options.sendStats(Object.assign(Object.assign({}, requestData), { responseSize: getRestResponseSize((_h = error === null || error === void 0 ? void 0 : error.response) === null || _h === void 0 ? void 0 : _h.data, ctx, ErrorConstructor), restStatus: responseStatus, userId }), (0, redact_sensitive_headers_1.redactSensitiveHeaders)(parentCtx, headers), parentCtx, { debugHeaders: (0, common_1.sanitizeDebugHeaders)(debugHeaders) });
343
+ options.sendStats(Object.assign(Object.assign({}, requestData), { responseSize: getRestResponseSize((_j = error === null || error === void 0 ? void 0 : error.response) === null || _j === void 0 ? void 0 : _j.data, ctx, ErrorConstructor), restStatus: responseStatus, userId }), (0, redact_sensitive_headers_1.redactSensitiveHeaders)(parentCtx, headers), parentCtx, { debugHeaders: (0, common_1.sanitizeDebugHeaders)(debugHeaders) });
344
344
  }
345
345
  else {
346
346
  ctx.stats(Object.assign(Object.assign({}, requestData), { responseStatus }));
package/build/index.js CHANGED
@@ -85,7 +85,7 @@ function createApiAction(schema, config, serviceKey, actionName, api, grpcContex
85
85
  validationSchema: config.validationSchema,
86
86
  encodePathArgs: config.encodePathArgs,
87
87
  getAuthHeaders: config.getAuthHeaders,
88
- }, config.ErrorConstructor);
88
+ }, config.ErrorConstructor, serviceSchema);
89
89
  }
90
90
  const grpcRecreateService = (_a = config.grpcRecreateService) !== null && _a !== void 0 ? _a : true;
91
91
  return (0, grpc_1.default)(grpcContext, endpointsConfig, action, serviceKey, actionName, {
@@ -98,7 +98,7 @@ function createApiAction(schema, config, serviceKey, actionName, api, grpcContex
98
98
  grpcOptions: config.grpcOptions,
99
99
  grpcRecreateService,
100
100
  getAuthHeaders: config.getAuthHeaders,
101
- }, config.ErrorConstructor);
101
+ }, config.ErrorConstructor, serviceSchema);
102
102
  }
103
103
  function generateGatewayApi(schema, config, grpcContext, baseApi) {
104
104
  const { installation, env } = config;
@@ -117,7 +117,7 @@ function generateGatewayApi(schema, config, grpcContext, baseApi) {
117
117
  function generateGatewayApiController(schemasByScope, Api, config, controllerActions) {
118
118
  // eslint-disable-next-line complexity
119
119
  return async function gateway(req, res) {
120
- var _a, _b, _c;
120
+ var _a, _b, _c, _d;
121
121
  const { userId } = res.locals || {};
122
122
  const { service, action, scope = 'root' } = req.params;
123
123
  const withDebugHeaders = typeof config.withDebugHeaders === 'function'
@@ -192,12 +192,15 @@ function generateGatewayApiController(schemasByScope, Api, config, controllerAct
192
192
  throw { error, debugHeaders: {} };
193
193
  }
194
194
  }
195
+ const serviceSchema = (_d = schemasByScope[scope]) === null || _d === void 0 ? void 0 : _d[service];
195
196
  const { responseData, responseHeaders, debugHeaders } = await apiAction({
196
197
  requestId: req.id,
197
198
  headers: req.headers,
198
199
  ctx: req.ctx,
199
200
  args,
200
- authArgs: config.getAuthArgs(req, res),
201
+ authArgs: (serviceSchema === null || serviceSchema === void 0 ? void 0 : serviceSchema.getAuthArgs)
202
+ ? serviceSchema.getAuthArgs(req, res)
203
+ : config.getAuthArgs(req, res),
201
204
  userId,
202
205
  abortSignal: abortController.signal,
203
206
  });
@@ -256,7 +259,7 @@ function getGatewayControllers(schemasByScope, config) {
256
259
  console.warn('Error when parse GATEWAY_ENDPOINTS_OVERRIDES', err);
257
260
  }
258
261
  }
259
- const credentials = (0, grpc_1.getCredentialsMap)(config.caCertificatePath);
262
+ const credentials = (0, grpc_1.getCredentialsMap)(config.caCertificatePath, config.clientCertificatePath, config.clientKeyPath);
260
263
  for (const scope of (0, common_1.getKeys)(schemasByScope)) {
261
264
  apiByScope[scope] = generateGatewayApi(schemasByScope[scope], config, { root: (0, grpc_1.createRoot)(config.includeProtoRoots), credentials }, apiByScope);
262
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;
@@ -199,6 +205,8 @@ export interface BaseSchema {
199
205
  actions: Record<string, ApiServiceActionConfig<any, any, any, any, any, any>>;
200
206
  serviceName?: string;
201
207
  endpoints?: Record<string, Record<string, EndpointsConfig>>;
208
+ getAuthHeaders?: GetAuthHeaders;
209
+ getAuthArgs?: (req: Request, res: Response) => Record<string, unknown> | undefined;
202
210
  };
203
211
  }
204
212
  export interface SchemasByScope {
@@ -272,6 +280,8 @@ export interface GatewayConfig<Context extends GatewayContext, Req extends Gatew
272
280
  sendStats?: SendStats<Context>;
273
281
  includeProtoRoots?: string[];
274
282
  caCertificatePath: string | null;
283
+ clientCertificatePath?: string | null;
284
+ clientKeyPath?: string | null;
275
285
  proxyHeaders: ProxyHeaders;
276
286
  proxyDebugHeaders?: ProxyHeaders;
277
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.7.2",
3
+ "version": "4.9.0",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "main": "build/index.js",