Skip to content

Commit 1cfe5e8

Browse files
committed
express 5: migrating routes, middleware for project ID regex, but still open issues...
1 parent e86b00e commit 1cfe5e8

File tree

5 files changed

+37
-28
lines changed

5 files changed

+37
-28
lines changed

src/packages/hub/proxy/index.ts

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
*/
55

66
import { Application } from "express";
7+
8+
import base_path from "@cocalc/backend/base-path";
9+
import { ProjectControlFunction } from "@cocalc/server/projects/control";
710
import getLogger from "../logger";
811
import initRequest from "./handle-request";
912
import initUpgrade from "./handle-upgrade";
10-
import base_path from "@cocalc/backend/base-path";
11-
import { ProjectControlFunction } from "@cocalc/server/projects/control";
1213

1314
const logger = getLogger("proxy");
1415

@@ -20,27 +21,29 @@ interface Options {
2021
proxyConat: boolean;
2122
}
2223

24+
const uuidRegex =
25+
/^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
26+
27+
function uuidMiddleware(req, _res, next) {
28+
if (uuidRegex.test(req.params.project_id)) {
29+
return next();
30+
}
31+
// Not a valid project ID UUID: skip to next matching route
32+
return next("route");
33+
}
34+
2335
export default function initProxy(opts: Options) {
24-
const proxy_regexp = `^${
25-
base_path.length <= 1 ? "" : base_path
26-
}/[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}/`;
27-
const proxy_pattern = `${
28-
base_path.length <= 1 ? "" : base_path
29-
}/:project_id/*splat`;
30-
logger.info(
31-
"creating proxy server with proxy_regexp",
32-
proxy_regexp,
33-
"proxy_pattern",
34-
proxy_pattern,
35-
);
36-
37-
// tcp connections:
36+
const prefix = base_path.length <= 1 ? "" : base_path;
37+
const routePath = `${prefix}/:project_id/*splat`;
38+
logger.info("creating proxy server for UUIDs only", routePath);
39+
3840
const handleProxy = initRequest(opts);
3941

40-
// websocket upgrades:
42+
const proxy_regexp = `^${prefix}\/[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$\/(.*)$`;
4143
const handleUpgrade = initUpgrade(opts, proxy_regexp);
4244

43-
opts.app.all(proxy_pattern, handleProxy);
45+
// Only handles proxy if the project_id is a valid UUID:
46+
opts.app.all(routePath, uuidMiddleware, handleProxy);
4447

4548
opts.httpServer.on("upgrade", handleUpgrade);
4649
}

src/packages/hub/servers/app/app-redirect.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
This redirect is *undone* in @cocalc/frontend/client/handle-hash-url.ts
55
*/
66

7-
import { join } from "path";
7+
import { join } from "node:path";
88
import { Router } from "express";
9+
910
import basePath from "@cocalc/backend/base-path";
1011
import { getLogger } from "@cocalc/hub/logger";
1112
import { APP_ROUTES } from "@cocalc/util/routing/app";
@@ -14,7 +15,8 @@ export default function init(router: Router) {
1415
const winston = getLogger("app-redirect");
1516
const v: string[] = [];
1617
for (const path of APP_ROUTES) {
17-
v.push(`/${path}/*splat`);
18+
v.push(`/${path}`);
19+
v.push(`/${path}/{*splat}`);
1820
}
1921
router.get(v, (req, res) => {
2022
winston.debug(req.url);

src/packages/hub/servers/app/next.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ import { join } from "path";
1111

1212
// @ts-ignore -- TODO: typescript doesn't like @cocalc/next/init (it is a js file).
1313
import initNextServer from "@cocalc/next/init";
14+
1415
import basePath from "@cocalc/backend/base-path";
1516
import { getLogger } from "@cocalc/hub/logger";
1617
import handleRaw from "@cocalc/next/lib/share/handle-raw";
1718
import { callback2 } from "@cocalc/util/async-utils";
19+
import { separate_file_extension } from "@cocalc/util/misc";
1820
import { database } from "../database";
1921
import createLandingRedirect from "./landing-redirect";
2022
import shareRedirect from "./share-redirect";
21-
import { separate_file_extension } from "@cocalc/util/misc";
2223

2324
export default async function init(app: Application) {
2425
const winston = getLogger("nextjs");
@@ -95,23 +96,24 @@ export default async function init(app: Application) {
9596
// 3: Redirects for backward compat; unfortunately there's slight
9697
// overhead for doing this on every request.
9798

98-
app.all(join(shareBasePath, "*splat"), shareRedirect(shareBasePath));
99+
app.all(join(shareBasePath), shareRedirect(shareBasePath));
100+
app.all(join(shareBasePath, "{*splat}"), shareRedirect(shareBasePath));
99101
}
100102

101103
const landingRedirect = createLandingRedirect();
102104
app.all(join(basePath, "index.html"), landingRedirect);
103105
app.all(join(basePath, "doc"), landingRedirect);
104-
app.all(join(basePath, "doc/*splat"), landingRedirect);
106+
app.all(join(basePath, "doc", "{*splat}"), landingRedirect);
105107
app.all(join(basePath, "policies"), landingRedirect);
106-
app.all(join(basePath, "policies/*splat"), landingRedirect);
108+
app.all(join(basePath, "policies", "{*splat}"), landingRedirect);
107109

108110
// The next.js server that serves everything else.
109111
winston.info(
110112
"Now using next.js packages/share handler to handle all endpoints not otherwise handled",
111113
);
112114

113115
// nextjs listens on everything else
114-
app.all("*splat", handler);
116+
app.all("{*splat}", handler);
115117
}
116118

117119
function parseURL(req: Request, base): { id: string; path: string } {

src/packages/project/directory-listing.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ Browser client code only uses this through the websocket anyways.
1818
*/
1919

2020
import { Router } from "express";
21+
import { join } from "node:path";
22+
2123
import getListing from "@cocalc/backend/get-listing";
2224

2325
export default function init(): Router {
2426
const base = "/.smc/directory_listing/";
2527
const router = Router();
2628

27-
router.get(base + "*splat", async (req, res) => {
29+
router.get(join(base, "{*splat}"), async (req, res) => {
2830
// decodeURIComponent because decodeURI(misc.encode_path('asdf/te #1/')) != 'asdf/te #1/'
2931
// https://github.com/sagemathinc/cocalc/issues/2400
3032
const path = decodeURIComponent(req.path.slice(base.length).trim());

src/packages/project/http-api/server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ function configure(server: express.Application, dbg: Function): void {
7474
}
7575
};
7676

77-
server.get("/api/v1/*", handler);
78-
server.post("/api/v1/*", handler);
77+
server.get("/api/v1/{*splat}", handler);
78+
server.post("/api/v1/{*splat}", handler);
7979
}
8080

8181
function rateLimit(server: express.Application): void {

0 commit comments

Comments
 (0)