Skip to content

Commit bbf2e24

Browse files
authored
Add skip-auth-preflight flag to allow OPTIONS requests through proxy (#7284)
1 parent 9045919 commit bbf2e24

File tree

6 files changed

+34
-1
lines changed

6 files changed

+34
-1
lines changed

Diff for: src/node/cli.ts

+5
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
8484
"trusted-origins"?: string[]
8585
version?: boolean
8686
"proxy-domain"?: string[]
87+
"skip-auth-preflight"?: boolean
8788
"reuse-window"?: boolean
8889
"new-window"?: boolean
8990
"ignore-last-opened"?: boolean
@@ -252,6 +253,10 @@ export const options: Options<Required<UserProvidedArgs>> = {
252253
description: "GitHub authentication token (can only be passed in via $GITHUB_TOKEN or the config file).",
253254
},
254255
"proxy-domain": { type: "string[]", description: "Domain used for proxying ports." },
256+
"skip-auth-preflight": {
257+
type: "boolean",
258+
description: "Allows preflight requests through proxy without authentication.",
259+
},
255260
"ignore-last-opened": {
256261
type: "boolean",
257262
short: "e",

Diff for: src/node/main.ts

+3
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ export const runCodeServer = async (
163163
logger.info(` - ${plural(args["proxy-domain"].length, "Proxying the following domain")}:`)
164164
args["proxy-domain"].forEach((domain) => logger.info(` - ${domain}`))
165165
}
166+
if (args["skip-auth-preflight"]) {
167+
logger.info(" - Skipping authentication for preflight requests")
168+
}
166169
if (process.env.VSCODE_PROXY_URI) {
167170
logger.info(`Using proxy URI in PORTS tab: ${process.env.VSCODE_PROXY_URI}`)
168171
}

Diff for: src/node/routes/domainProxy.ts

+5
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ router.all(/.*/, async (req, res, next) => {
6161

6262
ensureProxyEnabled(req)
6363

64+
if (req.method === "OPTIONS" && req.args["skip-auth-preflight"]) {
65+
// Allow preflight requests with `skip-auth-preflight` flag
66+
return next()
67+
}
68+
6469
// Must be authenticated to use the proxy.
6570
const isAuthenticated = await authenticated(req)
6671
if (!isAuthenticated) {

Diff for: src/node/routes/pathProxy.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ export async function proxy(
2626
): Promise<void> {
2727
ensureProxyEnabled(req)
2828

29-
if (!(await authenticated(req))) {
29+
if (req.method === "OPTIONS" && req.args["skip-auth-preflight"]) {
30+
// Allow preflight requests with `skip-auth-preflight` flag
31+
} else if (!(await authenticated(req))) {
3032
// If visiting the root (/:port only) redirect to the login page.
3133
if (!req.params.path || req.params.path === "/") {
3234
const to = self(req)

Diff for: test/unit/node/cli.test.ts

+3
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ describe("parser", () => {
108108

109109
["--abs-proxy-base-path", "/codeserver/app1"],
110110

111+
"--skip-auth-preflight",
112+
111113
["--session-socket", "/tmp/override-code-server-ipc-socket"],
112114

113115
["--host", "0.0.0.0"],
@@ -146,6 +148,7 @@ describe("parser", () => {
146148
"bind-addr": "192.169.0.1:8080",
147149
"session-socket": "/tmp/override-code-server-ipc-socket",
148150
"abs-proxy-base-path": "/codeserver/app1",
151+
"skip-auth-preflight": true,
149152
})
150153
})
151154

Diff for: test/unit/node/proxy.test.ts

+15
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,21 @@ describe("proxy", () => {
268268
const text = await resp.text()
269269
expect(text).toBe("app being served behind a prefixed path")
270270
})
271+
272+
it("should not allow OPTIONS without authentication by default", async () => {
273+
process.env.PASSWORD = "test"
274+
codeServer = await integration.setup(["--auth=password"])
275+
const resp = await codeServer.fetch(proxyPath, { method: "OPTIONS" })
276+
expect(resp.status).toBe(401)
277+
})
278+
279+
it("should allow OPTIONS with `skip-auth-preflight` flag", async () => {
280+
process.env.PASSWORD = "test"
281+
codeServer = await integration.setup(["--auth=password", "--skip-auth-preflight"])
282+
e.post("/wsup", (req, res) => {})
283+
const resp = await codeServer.fetch(proxyPath, { method: "OPTIONS" })
284+
expect(resp.status).toBe(200)
285+
})
271286
})
272287

273288
// NOTE@jsjoeio

0 commit comments

Comments
 (0)