Make authentication work with sub-domain proxy

This commit is contained in:
Asher 2020-10-26 15:13:52 -05:00
parent 112eda4605
commit 257d9a4fa4
No known key found for this signature in database
GPG Key ID: D63C1EF81242354A
1 changed files with 29 additions and 5 deletions

View File

@ -1,7 +1,7 @@
import { Request, Router } from "express"
import proxyServer from "http-proxy"
import { HttpCode } from "../common/http"
import { ensureAuthenticated } from "./http"
import { HttpCode, HttpError } from "../common/http"
import { authenticated, ensureAuthenticated } from "./http"
export const proxy = proxyServer.createProxyServer({})
proxy.on("error", (error, _, res) => {
@ -42,18 +42,39 @@ const maybeProxy = (req: Request): string | undefined => {
return undefined
}
// Must be authenticated to use the proxy.
ensureAuthenticated(req)
return port
}
/**
* Determine if the user is browsing /, /login, or static assets and if so fall
* through to allow the redirect and login flow.
*/
const shouldFallThrough = (req: Request): boolean => {
// The ideal would be to have a reliable way to detect if this is a request
// for (or originating from) our root or login HTML. But requests for HTML
// don't seem to set any content type.
return (
req.headers["content-type"] !== "application/json" &&
((req.originalUrl.startsWith("/") && req.method === "GET") ||
(req.originalUrl.startsWith("/static") && req.method === "GET") ||
(req.originalUrl.startsWith("/login") && (req.method === "GET" || req.method === "POST")))
)
}
router.all("*", (req, res, next) => {
const port = maybeProxy(req)
if (!port) {
return next()
}
// Must be authenticated to use the proxy.
if (!authenticated(req)) {
if (shouldFallThrough(req)) {
return next()
}
throw new HttpError("Unauthorized", HttpCode.Unauthorized)
}
proxy.web(req, res, {
ignorePath: true,
target: `http://127.0.0.1:${port}${req.originalUrl}`,
@ -66,6 +87,9 @@ router.ws("*", (socket, head, req, next) => {
return next()
}
// Must be authenticated to use the proxy.
ensureAuthenticated(req)
proxy.ws(req, socket, head, {
ignorePath: true,
target: `http://127.0.0.1:${port}${req.originalUrl}`,