@gravity-ui/gateway 2.5.0 → 2.5.2-alpha.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
@@ -124,6 +124,11 @@ interface GatewayConfig {
124
124
  }
125
125
  ```
126
126
 
127
+ #### validationSchema
128
+
129
+ By default, for path params in rest actions used the following regexp: `/^((?!(\.\.|\?|#|\\|\/)).)*$/i`.
130
+ If the parameter value does not pass validation, the `GATEWAY_INVALID_PARAM_VALUE` value is returned.
131
+
127
132
  ### Usage in Node.js
128
133
 
129
134
  Upon gateway initialization, in addition to exporting the controller, it also exports an `api` object, which represents the core for executing requests to the backend.
@@ -396,7 +396,8 @@ function createGrpcAction({ root, credentials }, endpoints, config, serviceKey,
396
396
  }
397
397
  }
398
398
  return async function action(actionConfig) {
399
- const { args, requestId, headers, ctx: parentCtx } = actionConfig;
399
+ var _a;
400
+ const { args, requestId, headers, ctx: parentCtx, userId } = actionConfig;
400
401
  const { action } = config;
401
402
  const lang = headers[constants_1.DEFAULT_LANG_HEADER] || constants_1.Lang.Ru; // header might be empty string
402
403
  const ctx = parentCtx.create(`Gateway ${serviceName} ${actionName} [grpc]`, {
@@ -415,6 +416,8 @@ function createGrpcAction({ root, credentials }, endpoints, config, serviceKey,
415
416
  requestId: actionConfig.requestId,
416
417
  requestMethod: action,
417
418
  requestUrl: config.protoKey,
419
+ traceId: ((_a = ctx.getTraceId) === null || _a === void 0 ? void 0 : _a.call(ctx)) || '',
420
+ userId: userId || '',
418
421
  };
419
422
  const debugHeaders = {
420
423
  'x-api-request-action': action,
@@ -39,8 +39,8 @@ function createRestAction(endpoints, config, serviceKey, actionName, options, Er
39
39
  const defaultAxiosClient = (0, axios_1.getAxiosClient)(timeout, config === null || config === void 0 ? void 0 : config.retries, options === null || options === void 0 ? void 0 : options.axiosConfig);
40
40
  /* eslint-disable complexity */
41
41
  return async function action(actionConfig) {
42
- var _a, _b, _c, _d, _e, _f, _g;
43
- const { args, requestId, headers: requestHeaders, ctx: parentCtx, authArgs } = actionConfig;
42
+ var _a, _b, _c, _d, _e, _f, _g, _h;
43
+ const { args, requestId, headers: requestHeaders, ctx: parentCtx, authArgs, userId, } = actionConfig;
44
44
  const debugHeaders = {};
45
45
  const lang = requestHeaders[constants_1.DEFAULT_LANG_HEADER] || constants_1.Lang.Ru; // header might be empty string
46
46
  const serviceName = (options === null || options === void 0 ? void 0 : options.serviceName) || serviceKey;
@@ -210,6 +210,8 @@ function createRestAction(endpoints, config, serviceKey, actionName, options, Er
210
210
  requestId,
211
211
  requestMethod: config.method,
212
212
  requestUrl: actionURL,
213
+ traceId: ((_f = ctx.getTraceId) === null || _f === void 0 ? void 0 : _f.call(ctx)) || '',
214
+ userId: userId || '',
213
215
  };
214
216
  const requestConfig = {
215
217
  url: actionURL,
@@ -245,7 +247,7 @@ function createRestAction(endpoints, config, serviceKey, actionName, options, Er
245
247
  const responseHeaders = {};
246
248
  const endRequestTime = Date.now();
247
249
  requestData.requestTime = endRequestTime - startRequestTime;
248
- const actualResponseContentType = (_f = response.headers) === null || _f === void 0 ? void 0 : _f['Content-Type'];
250
+ const actualResponseContentType = (_g = response.headers) === null || _g === void 0 ? void 0 : _g['Content-Type'];
249
251
  const expectedResponseContentType = config.expectedResponseContentType || options.expectedResponseContentType;
250
252
  if (actualResponseContentType && expectedResponseContentType) {
251
253
  let isInvalidResponseContentType;
@@ -342,10 +344,10 @@ function createRestAction(endpoints, config, serviceKey, actionName, options, Er
342
344
  }
343
345
  const responseStatus = lodash_1.default.get(parsedError, 'status') || lodash_1.default.get(error, 'status', 500);
344
346
  if (options === null || options === void 0 ? void 0 : options.sendStats) {
345
- options.sendStats(Object.assign(Object.assign({}, requestData), { responseSize: getRestResponseSize((_g = error === null || error === void 0 ? void 0 : error.response) === null || _g === void 0 ? void 0 : _g.data, ctx, ErrorConstructor), restStatus: responseStatus }), (0, redact_sensitive_headers_1.redactSensitiveHeaders)(parentCtx, headers), parentCtx, { debugHeaders: (0, common_1.sanitizeDebugHeaders)(debugHeaders) });
347
+ 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) });
346
348
  }
347
349
  else {
348
- ctx.stats(Object.assign(Object.assign({}, requestData), { responseStatus }));
350
+ ctx.stats(Object.assign(Object.assign({}, requestData), { responseStatus: 200 }));
349
351
  }
350
352
  ctx.logError('Request failed', error, {
351
353
  actionURL,
package/build/index.js CHANGED
@@ -112,6 +112,7 @@ function generateGatewayApiController(schemasByScope, Api, config, controllerAct
112
112
  // eslint-disable-next-line complexity
113
113
  return async function gateway(req, res) {
114
114
  var _a, _b, _c;
115
+ const { userId } = res.locals || {};
115
116
  const { service, action, scope = 'root' } = req.params;
116
117
  const withDebugHeaders = typeof config.withDebugHeaders === 'function'
117
118
  ? config.withDebugHeaders(req, res)
@@ -186,6 +187,7 @@ function generateGatewayApiController(schemasByScope, Api, config, controllerAct
186
187
  ctx: req.ctx,
187
188
  args,
188
189
  authArgs: config.getAuthArgs(req, res),
190
+ userId,
189
191
  });
190
192
  if (withDebugHeaders) {
191
193
  res.set(debugHeaders);
@@ -29,6 +29,7 @@ export interface ApiActionConfig<Context extends GatewayContext, TRequestData, T
29
29
  timeout?: number;
30
30
  callback?: (response: TResponseData) => void;
31
31
  authArgs?: Record<string, unknown>;
32
+ userId?: string;
32
33
  }
33
34
  export interface GRPCActionData {
34
35
  [key: string]: unknown;
@@ -47,6 +48,8 @@ export interface Stats {
47
48
  requestMethod: string;
48
49
  requestUrl: string;
49
50
  timestamp: number;
51
+ userId?: string;
52
+ traceId: string;
50
53
  }
51
54
  export type ControllerType = 'rest' | 'grpc';
52
55
  export interface GatewayError {
@@ -19,4 +19,5 @@ export interface GatewayContext {
19
19
  redactSensitiveKeys?: (headers: Dict) => Dict;
20
20
  };
21
21
  getMetadata: () => IncomingHttpHeaders;
22
+ getTraceId?: () => string;
22
23
  }
@@ -29,7 +29,7 @@ function encodePathParams(params) {
29
29
  }
30
30
  exports.encodePathParams = encodePathParams;
31
31
  function getPathParam(value) {
32
- return /^((?!(\.\.|\?|#|\\|\/)).)*$/i.test(value) ? value : '';
32
+ return /^((?!(\.\.|\?|#|\\|\/)).)*$/i.test(value) ? value : 'GATEWAY_INVALID_PARAM_VALUE';
33
33
  }
34
34
  exports.getPathParam = getPathParam;
35
35
  function getPathArgsProxy(args, encodePathArgs) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/gateway",
3
- "version": "2.5.0",
3
+ "version": "2.5.2-alpha.0",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "main": "build/index.js",