@nestjs/platform-fastify 11.1.13 → 11.1.14

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.
@@ -121,5 +121,8 @@ export declare class FastifyAdapter<TServer extends RawServerBase = RawServerDef
121
121
  private registerMiddie;
122
122
  private getRequestOriginalUrl;
123
123
  private injectRouteOptions;
124
+ private sanitizeUrl;
125
+ private removeDuplicateSlashes;
126
+ private trimLastSlash;
124
127
  }
125
128
  export {};
@@ -399,7 +399,7 @@ class FastifyAdapter extends http_adapter_1.AbstractHttpAdapter {
399
399
  let pathname = queryParamsIndex >= 0
400
400
  ? req.originalUrl.slice(0, queryParamsIndex)
401
401
  : req.originalUrl;
402
- pathname = (0, url_sanitizer_1.safeDecodeURI)(pathname).path;
402
+ pathname = this.sanitizeUrl(pathname);
403
403
  if (!re.exec(pathname + '/') && normalizedPath) {
404
404
  return next();
405
405
  }
@@ -501,5 +501,35 @@ class FastifyAdapter extends http_adapter_1.AbstractHttpAdapter {
501
501
  }
502
502
  return this.instance.route(routeToInject);
503
503
  }
504
+ sanitizeUrl(url) {
505
+ const initialConfig = this.instance.initialConfig;
506
+ const routerOptions = initialConfig.routerOptions;
507
+ if (routerOptions.ignoreDuplicateSlashes ||
508
+ initialConfig.ignoreDuplicateSlashes) {
509
+ url = this.removeDuplicateSlashes(url);
510
+ }
511
+ if (routerOptions.ignoreTrailingSlash ||
512
+ initialConfig.ignoreTrailingSlash) {
513
+ url = this.trimLastSlash(url);
514
+ }
515
+ if (routerOptions.caseSensitive === false ||
516
+ initialConfig.caseSensitive === false) {
517
+ url = url.toLowerCase();
518
+ }
519
+ return (0, url_sanitizer_1.safeDecodeURI)(url, routerOptions.useSemicolonDelimiter ||
520
+ initialConfig.useSemicolonDelimiter).path;
521
+ }
522
+ removeDuplicateSlashes(path) {
523
+ const REMOVE_DUPLICATE_SLASHES_REGEXP = /\/\/+/g;
524
+ return path.indexOf('//') !== -1
525
+ ? path.replace(REMOVE_DUPLICATE_SLASHES_REGEXP, '/')
526
+ : path;
527
+ }
528
+ trimLastSlash(path) {
529
+ if (path.length > 1 && path.charCodeAt(path.length - 1) === 47) {
530
+ return path.slice(0, -1);
531
+ }
532
+ return path;
533
+ }
504
534
  }
505
535
  exports.FastifyAdapter = FastifyAdapter;
@@ -5,17 +5,20 @@ const fastify_plugin_1 = require("fastify-plugin");
5
5
  const url_sanitizer_1 = require("find-my-way/lib/url-sanitizer");
6
6
  const path_to_regexp_1 = require("path-to-regexp");
7
7
  const reusify = require("reusify");
8
+ function bindLast(fn, last) {
9
+ return (...args) => fn(...args, last);
10
+ }
8
11
  /**
9
12
  * A clone of `@fastify/middie` engine https://github.com/fastify/middie
10
13
  * with an extra vulnerability fix. Path is now decoded before matching to
11
14
  * avoid bypassing middleware with encoded characters.
12
15
  */
13
- function middie(complete) {
16
+ function middie(complete, initialConfig) {
14
17
  const middlewares = [];
15
18
  const pool = reusify(Holder);
16
19
  return {
17
20
  use,
18
- run,
21
+ run: bindLast(run, initialConfig),
19
22
  };
20
23
  function use(url, f) {
21
24
  if (f === undefined) {
@@ -39,7 +42,7 @@ function middie(complete) {
39
42
  }
40
43
  return this;
41
44
  }
42
- function run(req, res, ctx) {
45
+ function run(req, res, ctx, initialConfig) {
43
46
  if (!middlewares.length) {
44
47
  complete(null, req, res, ctx);
45
48
  return;
@@ -50,6 +53,7 @@ function middie(complete) {
50
53
  holder.res = res;
51
54
  holder.url = sanitizeUrl(req.url);
52
55
  holder.context = ctx;
56
+ holder.initialConfig = initialConfig;
53
57
  holder.done();
54
58
  }
55
59
  function Holder() {
@@ -57,6 +61,7 @@ function middie(complete) {
57
61
  this.res = null;
58
62
  this.url = null;
59
63
  this.context = null;
64
+ this.initialConfig = null;
60
65
  this.i = 0;
61
66
  const that = this;
62
67
  this.done = function (err) {
@@ -78,7 +83,21 @@ function middie(complete) {
78
83
  const { fn, regexp } = middlewares[i];
79
84
  if (regexp) {
80
85
  // Decode URL before matching to avoid bypassing middleware
81
- const decodedUrl = (0, url_sanitizer_1.safeDecodeURI)(url).path;
86
+ let sanitizedUrl = url;
87
+ if (that.initialConfig.ignoreDuplicateSlashes ||
88
+ that.initialConfig.routerOptions?.ignoreDuplicateSlashes) {
89
+ sanitizedUrl = removeDuplicateSlashes(sanitizedUrl);
90
+ }
91
+ if (that.initialConfig.ignoreTrailingSlash ||
92
+ that.initialConfig.routerOptions?.ignoreTrailingSlash) {
93
+ sanitizedUrl = trimLastSlash(sanitizedUrl);
94
+ }
95
+ if (that.initialConfig.caseSensitive === false ||
96
+ that.initialConfig.routerOptions?.caseSensitive === false) {
97
+ sanitizedUrl = sanitizedUrl.toLowerCase();
98
+ }
99
+ const decodedUrl = (0, url_sanitizer_1.safeDecodeURI)(sanitizedUrl, that.initialConfig?.routerOptions?.useSemicolonDelimiter ||
100
+ that.initialConfig?.useSemicolonDelimiter).path;
82
101
  const result = regexp.exec(decodedUrl);
83
102
  if (result) {
84
103
  req.url = req.url.replace(result[0], '');
@@ -99,11 +118,24 @@ function middie(complete) {
99
118
  that.req = null;
100
119
  that.res = null;
101
120
  that.context = null;
121
+ that.initialConfig = null;
102
122
  that.i = 0;
103
123
  pool.release(that);
104
124
  }
105
125
  }
106
126
  }
127
+ function removeDuplicateSlashes(path) {
128
+ const REMOVE_DUPLICATE_SLASHES_REGEXP = /\/\/+/g;
129
+ return path.indexOf('//') !== -1
130
+ ? path.replace(REMOVE_DUPLICATE_SLASHES_REGEXP, '/')
131
+ : path;
132
+ }
133
+ function trimLastSlash(path) {
134
+ if (path.length > 1 && path.charCodeAt(path.length - 1) === 47) {
135
+ return path.slice(0, -1);
136
+ }
137
+ return path;
138
+ }
107
139
  function sanitizeUrl(url) {
108
140
  for (let i = 0, len = url.length; i < len; i++) {
109
141
  const charCode = url.charCodeAt(i);
@@ -144,7 +176,7 @@ function fastifyMiddie(fastify, options, next) {
144
176
  fastify.decorate('use', use);
145
177
  fastify[kMiddlewares] = [];
146
178
  fastify[kMiddieHasMiddlewares] = false;
147
- fastify[kMiddie] = middie(onMiddieEnd);
179
+ fastify[kMiddie] = middie(onMiddieEnd, fastify.initialConfig);
148
180
  const hook = options.hook || 'onRequest';
149
181
  if (!supportedHooks.includes(hook)) {
150
182
  next(new Error(`The hook "${hook}" is not supported by fastify-middie`));
@@ -198,7 +230,7 @@ function fastifyMiddie(fastify, options, next) {
198
230
  function onRegister(instance) {
199
231
  const middlewares = instance[kMiddlewares].slice();
200
232
  instance[kMiddlewares] = [];
201
- instance[kMiddie] = middie(onMiddieEnd);
233
+ instance[kMiddie] = middie(onMiddieEnd, instance.initialConfig);
202
234
  instance[kMiddieHasMiddlewares] = false;
203
235
  instance.decorate('use', use);
204
236
  for (const middleware of middlewares) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestjs/platform-fastify",
3
- "version": "11.1.13",
3
+ "version": "11.1.14",
4
4
  "description": "Nest - modern, fast, powerful node.js web framework (@platform-fastify)",
5
5
  "author": "Kamil Mysliwiec",
6
6
  "license": "MIT",
@@ -43,5 +43,5 @@
43
43
  "optional": true
44
44
  }
45
45
  },
46
- "gitHead": "e3a958ac3efebe7995e6d487e00bbc6fd6267fd5"
46
+ "gitHead": "5d31df7eb62d89952d827eadc19123fb441f541e"
47
47
  }
@@ -1,28 +0,0 @@
1
- /**
2
- * @see https://github.com/fastify/point-of-view/blob/master/index.d.ts
3
- */
4
- export interface PointOfViewOptions {
5
- engine: {
6
- ejs?: any;
7
- eta?: any;
8
- nunjucks?: any;
9
- pug?: any;
10
- handlebars?: any;
11
- mustache?: any;
12
- 'art-template'?: any;
13
- twig?: any;
14
- liquid?: any;
15
- dot?: any;
16
- };
17
- templates?: string;
18
- includeViewExtension?: boolean;
19
- options?: object;
20
- charset?: string;
21
- maxCache?: number;
22
- production?: boolean;
23
- defaultContext?: object;
24
- layout?: string;
25
- root?: string;
26
- viewExt?: string;
27
- propertyName?: string;
28
- }
@@ -1,5 +0,0 @@
1
- "use strict";
2
- /**
3
- * @see https://github.com/fastify/point-of-view/blob/master/index.d.ts
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });