Skip to content

Commit a018a6d

Browse files
jenn-newtonclaude
andcommitted
Apply Prettier formatting
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent fa2e6b0 commit a018a6d

File tree

3 files changed

+40
-28
lines changed

3 files changed

+40
-28
lines changed

client/src/components/AuthDebugger.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,15 +171,16 @@ const AuthDebugger = ({
171171
updateAuthState({
172172
...currentState,
173173
isInitiatingAuth: false,
174-
latestError: error instanceof Error ? error : new Error(String(error)),
174+
latestError:
175+
error instanceof Error ? error : new Error(String(error)),
175176
statusMessage: {
176177
type: "error",
177178
message: `Invalid authorization URL: ${error instanceof Error ? error.message : String(error)}`,
178179
},
179180
});
180181
return;
181182
}
182-
183+
183184
// Store the current auth state before redirecting
184185
sessionStorage.setItem(
185186
SESSION_KEYS.AUTH_DEBUGGER_STATE,

client/src/utils/__tests__/urlValidation.test.ts

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,73 +11,77 @@ describe("validateRedirectUrl", () => {
1111
});
1212

1313
it("should allow URLs with ports", () => {
14-
expect(() => validateRedirectUrl("https://example.com:8080")).not.toThrow();
14+
expect(() =>
15+
validateRedirectUrl("https://example.com:8080"),
16+
).not.toThrow();
1517
});
1618

1719
it("should allow URLs with paths", () => {
18-
expect(() => validateRedirectUrl("https://example.com/path/to/auth")).not.toThrow();
20+
expect(() =>
21+
validateRedirectUrl("https://example.com/path/to/auth"),
22+
).not.toThrow();
1923
});
2024

2125
it("should allow URLs with query parameters", () => {
22-
expect(() => validateRedirectUrl("https://example.com?param=value")).not.toThrow();
26+
expect(() =>
27+
validateRedirectUrl("https://example.com?param=value"),
28+
).not.toThrow();
2329
});
2430
});
2531

2632
describe("invalid URLs - XSS vectors", () => {
2733
it("should block javascript: protocol", () => {
2834
expect(() => validateRedirectUrl("javascript:alert('XSS')")).toThrow(
29-
"Authorization URL must be HTTP or HTTPS"
35+
"Authorization URL must be HTTP or HTTPS",
3036
);
3137
});
3238

3339
it("should block javascript: with encoded characters", () => {
34-
expect(() => validateRedirectUrl("javascript:alert%28%27XSS%27%29")).toThrow(
35-
"Authorization URL must be HTTP or HTTPS"
36-
);
40+
expect(() =>
41+
validateRedirectUrl("javascript:alert%28%27XSS%27%29"),
42+
).toThrow("Authorization URL must be HTTP or HTTPS");
3743
});
3844

3945
it("should block data: protocol", () => {
40-
expect(() => validateRedirectUrl("data:text/html,<script>alert('XSS')</script>")).toThrow(
41-
"Authorization URL must be HTTP or HTTPS"
42-
);
46+
expect(() =>
47+
validateRedirectUrl("data:text/html,<script>alert('XSS')</script>"),
48+
).toThrow("Authorization URL must be HTTP or HTTPS");
4349
});
4450

4551
it("should block vbscript: protocol", () => {
4652
expect(() => validateRedirectUrl("vbscript:msgbox")).toThrow(
47-
"Authorization URL must be HTTP or HTTPS"
53+
"Authorization URL must be HTTP or HTTPS",
4854
);
4955
});
5056

5157
it("should block file: protocol", () => {
5258
expect(() => validateRedirectUrl("file:///etc/passwd")).toThrow(
53-
"Authorization URL must be HTTP or HTTPS"
59+
"Authorization URL must be HTTP or HTTPS",
5460
);
5561
});
5662

5763
it("should block about: protocol", () => {
5864
expect(() => validateRedirectUrl("about:blank")).toThrow(
59-
"Authorization URL must be HTTP or HTTPS"
65+
"Authorization URL must be HTTP or HTTPS",
6066
);
6167
});
6268

6369
it("should block custom protocols", () => {
6470
expect(() => validateRedirectUrl("custom://example")).toThrow(
65-
"Authorization URL must be HTTP or HTTPS"
71+
"Authorization URL must be HTTP or HTTPS",
6672
);
6773
});
6874
});
6975

7076
describe("edge cases", () => {
7177
it("should handle malformed URLs", () => {
7278
expect(() => validateRedirectUrl("not a url")).toThrow(
73-
"Invalid URL: not a url"
79+
"Invalid URL: not a url",
7480
);
7581
});
7682

7783
it("should handle empty string", () => {
78-
expect(() => validateRedirectUrl("")).toThrow(
79-
"Invalid URL: "
80-
);
84+
expect(() => validateRedirectUrl("")).toThrow("Invalid URL: ");
8185
});
8286

8387
it("should handle URLs with unicode characters", () => {
@@ -91,12 +95,14 @@ describe("validateRedirectUrl", () => {
9195

9296
it("should handle protocol-relative URLs as invalid", () => {
9397
expect(() => validateRedirectUrl("//example.com")).toThrow(
94-
"Invalid URL: //example.com"
98+
"Invalid URL: //example.com",
9599
);
96100
});
97101

98102
it("should handle URLs with authentication", () => {
99-
expect(() => validateRedirectUrl("https://user:[email protected]")).not.toThrow();
103+
expect(() =>
104+
validateRedirectUrl("https://user:[email protected]"),
105+
).not.toThrow();
100106
});
101107
});
102108

@@ -107,7 +113,9 @@ describe("validateRedirectUrl", () => {
107113
});
108114

109115
it("should handle null bytes", () => {
110-
expect(() => validateRedirectUrl("java\x00script:alert('XSS')")).toThrow();
116+
expect(() =>
117+
validateRedirectUrl("java\x00script:alert('XSS')"),
118+
).toThrow();
111119
});
112120

113121
it("should handle tab characters", () => {
@@ -120,8 +128,8 @@ describe("validateRedirectUrl", () => {
120128

121129
it("should handle mixed case protocols", () => {
122130
expect(() => validateRedirectUrl("JaVaScRiPt:alert('XSS')")).toThrow(
123-
"Authorization URL must be HTTP or HTTPS"
131+
"Authorization URL must be HTTP or HTTPS",
124132
);
125133
});
126134
});
127-
});
135+
});

client/src/utils/urlValidation.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* Validates that a URL is safe for redirection.
33
* Only allows HTTP and HTTPS protocols to prevent XSS attacks.
4-
*
4+
*
55
* @param url - The URL string to validate
66
* @throws Error if the URL has an unsafe protocol
77
*/
@@ -12,10 +12,13 @@ export function validateRedirectUrl(url: string): void {
1212
throw new Error("Authorization URL must be HTTP or HTTPS");
1313
}
1414
} catch (error) {
15-
if (error instanceof Error && error.message === "Authorization URL must be HTTP or HTTPS") {
15+
if (
16+
error instanceof Error &&
17+
error.message === "Authorization URL must be HTTP or HTTPS"
18+
) {
1619
throw error;
1720
}
1821
// If URL parsing fails, it's also invalid
1922
throw new Error(`Invalid URL: ${url}`);
2023
}
21-
}
24+
}

0 commit comments

Comments
 (0)