1
1
import { Request , Router } from "express"
2
2
import proxyServer from "http-proxy"
3
3
import { HttpCode , HttpError } from "../common/http"
4
- import { authenticated , ensureAuthenticated } from "./http"
4
+ import { authenticated , ensureAuthenticated , redirect } from "./http"
5
5
import { Router as WsRouter } from "./wsRouter"
6
6
7
7
export const proxy = proxyServer . createProxyServer ( { } )
@@ -44,25 +44,6 @@ const maybeProxy = (req: Request): string | undefined => {
44
44
return port
45
45
}
46
46
47
- /**
48
- * Determine if the user is browsing /, /login, or static assets and if so fall
49
- * through to allow the redirect and login flow.
50
- */
51
- const shouldFallThrough = ( req : Request ) : boolean => {
52
- // See if it looks like a request for the root or login HTML.
53
- if ( req . accepts ( "text/html" ) ) {
54
- if (
55
- ( req . path === "/" && req . method === "GET" ) ||
56
- ( / \/ l o g i n \/ ? / . test ( req . path ) && ( req . method === "GET" || req . method === "POST" ) )
57
- ) {
58
- return true
59
- }
60
- }
61
-
62
- // See if it looks like a request for a static asset.
63
- return req . path . startsWith ( "/static/" ) && req . method === "GET"
64
- }
65
-
66
47
router . all ( "*" , ( req , res , next ) => {
67
48
const port = maybeProxy ( req )
68
49
if ( ! port ) {
@@ -71,9 +52,27 @@ router.all("*", (req, res, next) => {
71
52
72
53
// Must be authenticated to use the proxy.
73
54
if ( ! authenticated ( req ) ) {
74
- if ( shouldFallThrough ( req ) ) {
55
+ // Let the assets through since they're used on the login page.
56
+ if ( req . path . startsWith ( "/static/" ) && req . method === "GET" ) {
75
57
return next ( )
76
58
}
59
+
60
+ // Assume anything that explicitly accepts text/html is a user browsing a
61
+ // page (as opposed to an xhr request). Don't use `req.accepts()` since
62
+ // *every* request that I've seen (in Firefox and Chromium at least)
63
+ // includes `*/*` making it always truthy.
64
+ if ( typeof req . headers . accepts === "string" && req . headers . accepts . split ( "," ) . includes ( "text/html" ) ) {
65
+ // Let the login through.
66
+ if ( / \/ l o g i n \/ ? / . test ( req . path ) ) {
67
+ return next ( )
68
+ }
69
+ // Redirect all other pages to the login.
70
+ return redirect ( req , res , "login" , {
71
+ to : req . path ,
72
+ } )
73
+ }
74
+
75
+ // Everything else gets an unauthorized message.
77
76
throw new HttpError ( "Unauthorized" , HttpCode . Unauthorized )
78
77
}
79
78
0 commit comments