11import { Request , Router } from "express"
22import proxyServer from "http-proxy"
3- import { HttpCode } from "../common/http"
4- import { ensureAuthenticated } from "./http"
3+ import { HttpCode , HttpError } from "../common/http"
4+ import { authenticated , ensureAuthenticated } from "./http"
55
66export const proxy = proxyServer . createProxyServer ( { } )
77proxy . on ( "error" , ( error , _ , res ) => {
@@ -42,18 +42,39 @@ const maybeProxy = (req: Request): string | undefined => {
4242 return undefined
4343 }
4444
45- // Must be authenticated to use the proxy.
46- ensureAuthenticated ( req )
47-
4845 return port
4946}
5047
48+ /**
49+ * Determine if the user is browsing /, /login, or static assets and if so fall
50+ * through to allow the redirect and login flow.
51+ */
52+ const shouldFallThrough = ( req : Request ) : boolean => {
53+ // The ideal would be to have a reliable way to detect if this is a request
54+ // for (or originating from) our root or login HTML. But requests for HTML
55+ // don't seem to set any content type.
56+ return (
57+ req . headers [ "content-type" ] !== "application/json" &&
58+ ( ( req . originalUrl . startsWith ( "/" ) && req . method === "GET" ) ||
59+ ( req . originalUrl . startsWith ( "/static" ) && req . method === "GET" ) ||
60+ ( req . originalUrl . startsWith ( "/login" ) && ( req . method === "GET" || req . method === "POST" ) ) )
61+ )
62+ }
63+
5164router . all ( "*" , ( req , res , next ) => {
5265 const port = maybeProxy ( req )
5366 if ( ! port ) {
5467 return next ( )
5568 }
5669
70+ // Must be authenticated to use the proxy.
71+ if ( ! authenticated ( req ) ) {
72+ if ( shouldFallThrough ( req ) ) {
73+ return next ( )
74+ }
75+ throw new HttpError ( "Unauthorized" , HttpCode . Unauthorized )
76+ }
77+
5778 proxy . web ( req , res , {
5879 ignorePath : true ,
5980 target : `http://127.0.0.1:${ port } ${ req . originalUrl } ` ,
@@ -66,6 +87,9 @@ router.ws("*", (socket, head, req, next) => {
6687 return next ( )
6788 }
6889
90+ // Must be authenticated to use the proxy.
91+ ensureAuthenticated ( req )
92+
6993 proxy . ws ( req , socket , head , {
7094 ignorePath : true ,
7195 target : `http://127.0.0.1:${ port } ${ req . originalUrl } ` ,
0 commit comments