fastify-txstate 3.0.4 → 3.0.5

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
@@ -10,11 +10,13 @@ const http_1 = __importDefault(require("http"));
10
10
  const http_status_codes_1 = require("http-status-codes");
11
11
  class Server {
12
12
  constructor(config = {}) {
13
- var _a, _b, _c;
13
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
14
14
  this.https = false;
15
15
  this.errorHandlers = [];
16
16
  this.shuttingDown = false;
17
+ this.validOrigins = {};
17
18
  this.validOriginHosts = {};
19
+ this.validOriginSuffixes = new Set();
18
20
  try {
19
21
  const key = fs_1.default.readFileSync('/securekeys/private.key');
20
22
  const cert = fs_1.default.readFileSync('/securekeys/cert.pem');
@@ -42,18 +44,41 @@ class Server {
42
44
  config.trustProxy = true;
43
45
  this.app = (0, fastify_1.fastify)(config);
44
46
  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 : [])]);
47
+ 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 : [])]);
48
+ 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 : [])]);
49
+ 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
50
  this.app.addHook('preHandler', async (req, res) => {
51
+ var _a;
47
52
  if (!req.headers.origin)
48
53
  return;
49
- const parsedOrigin = new URL(req.headers.origin);
50
- if (req.hostname.replace(/:\d+$/, '') !== parsedOrigin.hostname && !this.validOriginHosts[parsedOrigin.hostname]) {
54
+ let passed = this.validOrigins[req.headers.origin];
55
+ if (!passed) {
56
+ const parsedOrigin = new URL(req.headers.origin);
57
+ if (req.hostname.replace(/:\d+$/, '') === parsedOrigin.hostname)
58
+ passed = true;
59
+ if (this.validOriginHosts[parsedOrigin.hostname])
60
+ passed = true;
61
+ if (!passed && this.validOriginSuffixes.size > 0) {
62
+ const originParts = parsedOrigin.hostname.split('.');
63
+ for (let i = 0; i < originParts.length; i++) {
64
+ const suffix = originParts.slice(i).join('.');
65
+ if (this.validOriginSuffixes.has(suffix))
66
+ passed = true;
67
+ }
68
+ }
69
+ if (!passed && ((_a = config.checkOrigin) === null || _a === void 0 ? void 0 : _a.call(config, req)))
70
+ passed = true;
71
+ }
72
+ if (!passed) {
51
73
  await res.status(403).send('Origin check failed. Suspected XSRF attack.');
52
74
  return res;
53
75
  }
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']);
76
+ else {
77
+ void res.header('Access-Control-Allow-Origin', req.headers.origin);
78
+ void res.header('Access-Control-Max-Age', '600'); // ask browser to skip pre-flights for 10 minutes after a yes
79
+ if (req.headers['access-control-request-headers'])
80
+ void res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
81
+ }
57
82
  });
58
83
  this.app.options('*', async (req, res) => {
59
84
  await res.send();
@@ -133,8 +158,16 @@ class Server {
133
158
  setHealthy() {
134
159
  this.healthMessage = undefined;
135
160
  }
161
+ setValidOrigins(origins) {
162
+ this.validOrigins = origins.reduce((validOrigins, origin) => ({ ...validOrigins, [origin]: true }), {});
163
+ }
136
164
  setValidOriginHosts(hosts) {
137
- this.validOriginHosts = hosts.reduce((validOrigins, origin) => ({ ...validOrigins, [origin]: true }), {});
165
+ this.validOriginHosts = hosts.reduce((validHosts, host) => ({ ...validHosts, [host]: true }), {});
166
+ }
167
+ setValidOriginSuffixes(suffixes) {
168
+ this.validOriginSuffixes.clear();
169
+ for (const s of suffixes)
170
+ this.validOriginSuffixes.add(s);
138
171
  }
139
172
  async close(softSeconds) {
140
173
  var _a;
@@ -4,8 +4,11 @@ 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
  }
10
13
  export default class Server {
11
14
  protected https: boolean;
@@ -13,7 +16,9 @@ export default class Server {
13
16
  protected healthMessage?: string;
14
17
  protected shuttingDown: boolean;
15
18
  protected sigHandler: (signal: any) => void;
19
+ protected validOrigins: Record<string, boolean>;
16
20
  protected validOriginHosts: Record<string, boolean>;
21
+ protected validOriginSuffixes: Set<string>;
17
22
  app: FastifyInstance;
18
23
  constructor(config?: FastifyTxStateOptions & {
19
24
  http2?: true;
@@ -22,7 +27,9 @@ export default class Server {
22
27
  addErrorHandler(handler: ErrorHandler): void;
23
28
  setUnhealthy(message: string): void;
24
29
  setHealthy(): void;
30
+ setValidOrigins(origins: string[]): void;
25
31
  setValidOriginHosts(hosts: string[]): void;
32
+ setValidOriginSuffixes(suffixes: string[]): void;
26
33
  close(softSeconds?: number): Promise<void>;
27
34
  }
28
35
  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.5",
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",