fastify-txstate 3.0.4 → 3.0.6

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/lib/index.js CHANGED
@@ -3,18 +3,31 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.FailedValidationError = exports.HttpError = void 0;
6
+ exports.FailedValidationError = exports.HttpError = exports.devLogger = void 0;
7
7
  const fastify_1 = require("fastify");
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const http_1 = __importDefault(require("http"));
10
10
  const http_status_codes_1 = require("http-status-codes");
11
+ exports.devLogger = {
12
+ level: 'info',
13
+ info: console.info,
14
+ error: console.error,
15
+ debug: console.debug,
16
+ fatal: console.error,
17
+ warn: console.warn,
18
+ trace: console.trace,
19
+ silent: (msg) => { },
20
+ child(bindings, options) { return exports.devLogger; }
21
+ };
11
22
  class Server {
12
23
  constructor(config = {}) {
13
- var _a, _b, _c;
24
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
14
25
  this.https = false;
15
26
  this.errorHandlers = [];
16
27
  this.shuttingDown = false;
28
+ this.validOrigins = {};
17
29
  this.validOriginHosts = {};
30
+ this.validOriginSuffixes = new Set();
18
31
  try {
19
32
  const key = fs_1.default.readFileSync('/securekeys/private.key');
20
33
  const cert = fs_1.default.readFileSync('/securekeys/cert.pem');
@@ -33,27 +46,49 @@ class Server {
33
46
  delete config.https;
34
47
  }
35
48
  if (typeof config.logger === 'undefined') {
36
- config.logger = {
37
- level: 'info',
38
- prettyPrint: process.env.NODE_ENV === 'development'
39
- };
49
+ config.logger = process.env.NODE_ENV === 'development'
50
+ ? exports.devLogger
51
+ : { level: 'info' };
40
52
  }
41
53
  if (process.env.TRUST_PROXY)
42
54
  config.trustProxy = true;
43
55
  this.app = (0, fastify_1.fastify)(config);
44
56
  if (!config.skipOriginCheck && !process.env.SKIP_ORIGIN_CHECK) {
45
- this.setValidOriginHosts([...((_a = config.validOriginHosts) !== null && _a !== void 0 ? _a : []), ...((_c = (_b = process.env.VALID_ORIGIN_HOSTS) === null || _b === void 0 ? void 0 : _b.split(',')) !== null && _c !== void 0 ? _c : [])]);
57
+ this.setValidOrigins([...((_a = config.validOrigins) !== null && _a !== void 0 ? _a : []), ...((_c = (_b = process.env.VALID_ORIGINS) === null || _b === void 0 ? void 0 : _b.split(',')) !== null && _c !== void 0 ? _c : [])]);
58
+ this.setValidOriginHosts([...((_d = config.validOriginHosts) !== null && _d !== void 0 ? _d : []), ...((_f = (_e = process.env.VALID_ORIGIN_HOSTS) === null || _e === void 0 ? void 0 : _e.split(',')) !== null && _f !== void 0 ? _f : [])]);
59
+ this.setValidOriginSuffixes([...((_g = config.validOriginSuffixes) !== null && _g !== void 0 ? _g : []), ...((_j = (_h = process.env.VALID_ORIGIN_SUFFIXES) === null || _h === void 0 ? void 0 : _h.split(',')) !== null && _j !== void 0 ? _j : [])]);
46
60
  this.app.addHook('preHandler', async (req, res) => {
61
+ var _a;
47
62
  if (!req.headers.origin)
48
63
  return;
49
- const parsedOrigin = new URL(req.headers.origin);
50
- if (req.hostname.replace(/:\d+$/, '') !== parsedOrigin.hostname && !this.validOriginHosts[parsedOrigin.hostname]) {
64
+ let passed = this.validOrigins[req.headers.origin];
65
+ if (!passed) {
66
+ const parsedOrigin = new URL(req.headers.origin);
67
+ if (req.hostname.replace(/:\d+$/, '') === parsedOrigin.hostname)
68
+ passed = true;
69
+ if (this.validOriginHosts[parsedOrigin.hostname])
70
+ passed = true;
71
+ if (!passed && this.validOriginSuffixes.size > 0) {
72
+ const originParts = parsedOrigin.hostname.split('.');
73
+ for (let i = 0; i < originParts.length; i++) {
74
+ const suffix = originParts.slice(i).join('.');
75
+ if (this.validOriginSuffixes.has(suffix))
76
+ passed = true;
77
+ }
78
+ }
79
+ if (!passed && ((_a = config.checkOrigin) === null || _a === void 0 ? void 0 : _a.call(config, req)))
80
+ passed = true;
81
+ }
82
+ if (!passed) {
51
83
  await res.status(403).send('Origin check failed. Suspected XSRF attack.');
52
84
  return res;
53
85
  }
54
- void res.header('Access-Control-Allow-Origin', req.headers.origin);
55
- if (req.headers['access-control-request-headers'])
56
- void res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
86
+ else {
87
+ void res.header('Access-Control-Allow-Origin', req.headers.origin);
88
+ void res.header('Access-Control-Max-Age', '600'); // ask browser to skip pre-flights for 10 minutes after a yes
89
+ if (req.headers['access-control-request-headers'])
90
+ void res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
91
+ }
57
92
  });
58
93
  this.app.options('*', async (req, res) => {
59
94
  await res.send();
@@ -133,8 +168,16 @@ class Server {
133
168
  setHealthy() {
134
169
  this.healthMessage = undefined;
135
170
  }
171
+ setValidOrigins(origins) {
172
+ this.validOrigins = origins.reduce((validOrigins, origin) => ({ ...validOrigins, [origin]: true }), {});
173
+ }
136
174
  setValidOriginHosts(hosts) {
137
- this.validOriginHosts = hosts.reduce((validOrigins, origin) => ({ ...validOrigins, [origin]: true }), {});
175
+ this.validOriginHosts = hosts.reduce((validHosts, host) => ({ ...validHosts, [host]: true }), {});
176
+ }
177
+ setValidOriginSuffixes(suffixes) {
178
+ this.validOriginSuffixes.clear();
179
+ for (const s of suffixes)
180
+ this.validOriginSuffixes.add(s);
138
181
  }
139
182
  async close(softSeconds) {
140
183
  var _a;
@@ -4,16 +4,50 @@ import http2 from 'http2';
4
4
  declare type ErrorHandler = (error: Error, req: FastifyRequest, res: FastifyReply) => Promise<void>;
5
5
  export interface FastifyTxStateOptions extends Partial<FastifyServerOptions> {
6
6
  https?: http2.SecureServerOptions;
7
+ validOrigins?: string[];
7
8
  validOriginHosts?: string[];
9
+ validOriginSuffixes?: string[];
8
10
  skipOriginCheck?: boolean;
11
+ checkOrigin?: (req: FastifyRequest) => boolean;
9
12
  }
13
+ export declare const devLogger: {
14
+ level: string;
15
+ info: {
16
+ (...data: any[]): void;
17
+ (message?: any, ...optionalParams: any[]): void;
18
+ };
19
+ error: {
20
+ (...data: any[]): void;
21
+ (message?: any, ...optionalParams: any[]): void;
22
+ };
23
+ debug: {
24
+ (...data: any[]): void;
25
+ (message?: any, ...optionalParams: any[]): void;
26
+ };
27
+ fatal: {
28
+ (...data: any[]): void;
29
+ (message?: any, ...optionalParams: any[]): void;
30
+ };
31
+ warn: {
32
+ (...data: any[]): void;
33
+ (message?: any, ...optionalParams: any[]): void;
34
+ };
35
+ trace: {
36
+ (...data: any[]): void;
37
+ (message?: any, ...optionalParams: any[]): void;
38
+ };
39
+ silent: (msg: any) => void;
40
+ child(bindings: any, options?: any): any;
41
+ };
10
42
  export default class Server {
11
43
  protected https: boolean;
12
44
  protected errorHandlers: ErrorHandler[];
13
45
  protected healthMessage?: string;
14
46
  protected shuttingDown: boolean;
15
47
  protected sigHandler: (signal: any) => void;
48
+ protected validOrigins: Record<string, boolean>;
16
49
  protected validOriginHosts: Record<string, boolean>;
50
+ protected validOriginSuffixes: Set<string>;
17
51
  app: FastifyInstance;
18
52
  constructor(config?: FastifyTxStateOptions & {
19
53
  http2?: true;
@@ -22,7 +56,9 @@ export default class Server {
22
56
  addErrorHandler(handler: ErrorHandler): void;
23
57
  setUnhealthy(message: string): void;
24
58
  setHealthy(): void;
59
+ setValidOrigins(origins: string[]): void;
25
60
  setValidOriginHosts(hosts: string[]): void;
61
+ setValidOriginSuffixes(suffixes: string[]): void;
26
62
  close(softSeconds?: number): Promise<void>;
27
63
  }
28
64
  export declare class HttpError extends Error {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fastify-txstate",
3
- "version": "3.0.4",
3
+ "version": "3.0.6",
4
4
  "description": "A small wrapper for fastify providing a set of common conventions & utility functions we use.",
5
5
  "exports": {
6
6
  "types": "./lib-esm/index.d.ts",