Skip to content

Commit 04cc027

Browse files
committed
Add lib with JS build, typings.
Finish README content. Add query to test URL to ensure the query params are included in the redirect Location value. Renamed `HTTP_REQUIRED` to `HTTPS_REQUIRED`.
1 parent acfdee0 commit 04cc027

File tree

5 files changed

+72
-9
lines changed

5 files changed

+72
-9
lines changed

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
# fastify-https-always
2-
This fastify plugin recognizes http requests and either redirects to https or disallows the request. Useful to ensure connections utilize secure HTTP connection URLs. The logic is very similar to the [express-ssl](https://github.com/jclem/express-ssl) plugin. It can examine the request headers to determine if a request has been forwarded from a TLS-terminating proxy, a common deployment model.
2+
This fastify plugin recognizes http requests and either redirects to an https URL or disallows the request. Useful to ensure connections utilize secure HTTP connection URLs. The logic is very similar to the [express-ssl](https://github.com/jclem/express-ssl) plugin.
3+
4+
This plugin can examine the request headers to determine if a request has been forwarded from a TLS-terminating proxy, a common deployment model. It relies on fastify’s [trustProxy](https://www.fastify.io/docs/latest/Reference/Server/#trustproxy) setting to learn the protocol and host name of a request sent through a proxy, such as an API gateway or load balancer.
35

46
### Configuration
57

6-
### fastify's trustProxy
8+
This plugin has several optional configurations that can be used to change the behavior of the plugin. The following table lists these options for your configuration.
9+
10+
| Option | Default | Notes |
11+
| ---------------- | ----------------------------------------------------- | ------------------------------------------------------------ |
12+
| `enabled` | `true` | Enables the plugin. Useful in build systems where the plugin’s enabled state is driven by an environment variable. |
13+
| `productionOnly` | `true` | Only enable this plugin in production environments. Checks Node’s `NODE_ENV` environment variable for the standard `production` value. |
14+
| `redirect` | `true` | `http` requests will be redirected to the appropriate `https` service. If this config is false, then a `403 Forbidden` error is returned instead. |
15+
| `httpsPort` | `undefined` (spec uses 443 as the default https port) | Use this value to change the https port used in the redirect Location header. |
16+

lib/index.d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// <reference types="node" />
2+
import { FastifyPluginOptions } from "fastify";
3+
export interface HttpsAlwaysOptions extends FastifyPluginOptions {
4+
enabled?: boolean;
5+
productionOnly?: boolean;
6+
redirect?: boolean;
7+
httpsPort?: number;
8+
}
9+
declare const _default: import("fastify").FastifyPluginCallback<HttpsAlwaysOptions, import("http").Server>;
10+
export default _default;

lib/index.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"use strict";
2+
var __importDefault = (this && this.__importDefault) || function (mod) {
3+
return (mod && mod.__esModule) ? mod : { "default": mod };
4+
};
5+
Object.defineProperty(exports, "__esModule", { value: true });
6+
const error_1 = __importDefault(require("@fastify/error"));
7+
const fastify_plugin_1 = __importDefault(require("fastify-plugin"));
8+
const HTTPS_REQUIRED = (0, error_1.default)("FST_HTTPS_REQUIRED", "Please use HTTPS when communicating with this server.", 403);
9+
function handleRequest(ctx, request, reply, next) {
10+
const { port, redirect } = ctx;
11+
const { hostname, protocol, url } = request;
12+
if (protocol !== "https") {
13+
if (redirect) {
14+
const portIdx = hostname.lastIndexOf(":");
15+
const host = portIdx > 0 ? hostname.substring(0, portIdx) : hostname;
16+
const httpsUrl = `https://${host}${port}${url}`;
17+
reply.redirect(301, httpsUrl);
18+
}
19+
else {
20+
next(HTTPS_REQUIRED());
21+
return;
22+
}
23+
}
24+
next();
25+
}
26+
function plugin(fastify, opts, next) {
27+
const { enabled = true, productionOnly = true, redirect = true, httpsPort } = opts;
28+
if (enabled) {
29+
const inProd = process.env.NODE_ENV === "production";
30+
if (!productionOnly || inProd) {
31+
const ctx = {
32+
redirect,
33+
port: httpsPort ? `:${httpsPort}` : ""
34+
};
35+
fastify.addHook("onRequest", (q, p, d) => handleRequest(ctx, q, p, d));
36+
}
37+
}
38+
next();
39+
}
40+
exports.default = (0, fastify_plugin_1.default)(plugin, {
41+
name: "fastify-https-always",
42+
fastify: ">=3.x"
43+
});

src/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import fp from "fastify-plugin"
44

55

66
export interface HttpsAlwaysOptions extends FastifyPluginOptions {
7-
productionOnly?: boolean
87
enabled?: boolean
9-
httpsPort?: number
8+
productionOnly?: boolean
109
redirect?: boolean
10+
httpsPort?: number
1111
}
1212

1313

@@ -17,7 +17,7 @@ type HttpsAlwaysContext = {
1717
}
1818

1919

20-
const HTTP_REQUIRED = createError(
20+
const HTTPS_REQUIRED = createError(
2121
"FST_HTTPS_REQUIRED",
2222
"Please use HTTPS when communicating with this server.",
2323
403)
@@ -45,7 +45,7 @@ function handleRequest(ctx: HttpsAlwaysContext,
4545
const httpsUrl = `https://${host}${port}${url}`
4646
reply.redirect(301, httpsUrl)
4747
} else {
48-
next(HTTP_REQUIRED())
48+
next(HTTPS_REQUIRED())
4949
return
5050
}
5151
}
@@ -60,13 +60,13 @@ function plugin(fastify: FastifyInstance,
6060
const {
6161
enabled = true,
6262
productionOnly = true,
63-
httpsPort,
6463
redirect = true,
64+
httpsPort
6565
} = opts
6666

6767
if (enabled) {
6868
const inProd = process.env.NODE_ENV === "production"
69-
if (!productionOnly || (productionOnly && inProd)) {
69+
if (!productionOnly || inProd) {
7070
const ctx: HttpsAlwaysContext = {
7171
redirect,
7272
port: httpsPort ? `:${httpsPort}` : ""

test/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import httpsAlwaysPlugin, {HttpsAlwaysOptions} from "../src"
77
// self-signed testing cert
88
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
99

10-
const URL = "/a/url"
10+
const URL = "/a/url?qp=hi"
1111

1212
test("Tests for https-always", async (t) => {
1313
const https = Fastify({

0 commit comments

Comments
 (0)