Skip to content

Commit 22efd87

Browse files
authored
fix: remove trailing slash in origins; add unit test framework (#356)
1 parent 56f7414 commit 22efd87

File tree

6 files changed

+1651
-42
lines changed

6 files changed

+1651
-42
lines changed

jest.config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
preset: "ts-jest",
3+
testEnvironment: "node",
4+
// Add any other Jest configuration options here
5+
};

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"lint": "eslint 'src/**/*.ts'",
2828
"lint:fix": "eslint --fix 'src/**/*.ts'",
2929
"test:load": "npx tsx ./test/load/index.ts",
30-
"test:load:benchmark": "npx tsx ./test/load/scripts/account.ts"
30+
"test:load:benchmark": "npx tsx ./test/load/scripts/account.ts",
31+
"test:unit": "jest"
3132
},
3233
"dependencies": {
3334
"@aws-sdk/client-kms": "^3.398.0",
@@ -78,6 +79,7 @@
7879
"@types/cookie": "^0.5.1",
7980
"@types/crypto-js": "^4.1.2",
8081
"@types/express": "^4.17.17",
82+
"@types/jest": "^29.5.11",
8183
"@types/node": "^18.15.4",
8284
"@types/node-cron": "^3.0.8",
8385
"@types/pg": "^8.6.6",
@@ -93,11 +95,13 @@
9395
"eslint": "^8.36.0",
9496
"eslint-config-prettier": "^8.7.0",
9597
"hardhat": "^2.1.2",
98+
"jest": "^29.7.0",
9699
"nodemon": "^2.0.21",
97100
"openapi-typescript-codegen": "^0.25.0",
98101
"prettier": "^2.8.7",
99102
"prompts": "^2.4.2",
100103
"supertest": "^6.3.3",
104+
"ts-jest": "^29.1.1",
101105
"ts-node": "^10.9.1",
102106
"typescript": "^5.1.3"
103107
},

src/server/middleware/cors.ts

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,33 @@ import { env } from "../../utils/env";
55
export const withCors = async (server: FastifyInstance) => {
66
const originArray = env.ACCESS_CONTROL_ALLOW_ORIGIN.split(",") as string[];
77
await server.register(fastifyCors, {
8-
origin: originArray.map((data) => {
9-
if (data.startsWith("/") && data.endsWith("/")) {
10-
return new RegExp(data.slice(1, -1));
11-
}
8+
origin: originArray.map(sanitizeOrigin),
9+
credentials: true,
10+
});
11+
};
1212

13-
if (data.startsWith("*.")) {
14-
const regex = data.replace("*.", ".*.");
15-
return new RegExp(regex);
16-
}
13+
export const sanitizeOrigin = (data: string): string | RegExp => {
14+
if (data.startsWith("/") && data.endsWith("/")) {
15+
return new RegExp(data.slice(1, -1));
16+
}
1717

18-
if (data.includes("thirdweb-preview.com")) {
19-
return new RegExp(/^https?:\/\/.*\.thirdweb-preview\.com$/);
20-
}
21-
if (data.includes("thirdweb-dev.com")) {
22-
return new RegExp(/^https?:\/\/.*\.thirdweb-dev\.com$/);
23-
}
18+
if (data.startsWith("*.")) {
19+
const regex = data.replace("*.", ".*.");
20+
return new RegExp(regex);
21+
}
2422

25-
return data;
26-
}),
27-
credentials: true,
28-
});
23+
if (data.includes("thirdweb-preview.com")) {
24+
return new RegExp(/^https?:\/\/.*\.thirdweb-preview\.com$/);
25+
}
26+
if (data.includes("thirdweb-dev.com")) {
27+
return new RegExp(/^https?:\/\/.*\.thirdweb-dev\.com$/);
28+
}
29+
30+
// Remove trailing slashes.
31+
// The origin header does not include a trailing slash.
32+
if (data.endsWith("/")) {
33+
return data.slice(0, -1);
34+
}
35+
36+
return data;
2937
};

src/tests/cors.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { sanitizeOrigin } from "../server/middleware/cors";
2+
3+
describe("sanitizeOrigin", () => {
4+
it("with leading and trailing slashes", () => {
5+
expect(sanitizeOrigin("/foobar/")).toEqual(RegExp("foobar"));
6+
});
7+
it("with leading wildcard", () => {
8+
expect(sanitizeOrigin("*.foobar.com")).toEqual(RegExp(".*.foobar.com"));
9+
});
10+
it("with thirdweb domains", () => {
11+
expect(sanitizeOrigin("https://thirdweb-preview.com")).toEqual(
12+
new RegExp(/^https?:\/\/.*\.thirdweb-preview\.com$/),
13+
);
14+
expect(sanitizeOrigin("https://thirdweb-dev.com")).toEqual(
15+
new RegExp(/^https?:\/\/.*\.thirdweb-dev\.com$/),
16+
);
17+
});
18+
it("with trailing slashes", () => {
19+
expect(sanitizeOrigin("https://foobar.com/")).toEqual("https://foobar.com");
20+
});
21+
it("fallback: don't change origin", () => {
22+
expect(sanitizeOrigin("https://foobar.com")).toEqual("https://foobar.com");
23+
});
24+
});

src/utils/env.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const boolSchema = (defaultBool: "true" | "false") =>
4545
export const env = createEnv({
4646
server: {
4747
NODE_ENV: z
48-
.enum(["production", "development", "testing", "local"])
48+
.enum(["production", "development", "test", "local"])
4949
.default("development"),
5050
LOG_LEVEL: z
5151
.enum(["fatal", "error", "warn", "info", "debug", "trace"])

0 commit comments

Comments
 (0)