Skip to content

Commit bd4c0a1

Browse files
committed
chore: correct url files
1 parent a97819b commit bd4c0a1

File tree

2 files changed

+63
-5
lines changed

2 files changed

+63
-5
lines changed

web/src/utils/linkUtils.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,28 @@
11
export const isExternalLink = (url: string): boolean => {
2+
if (!url || typeof url !== "string") {
3+
return false;
4+
}
5+
6+
const trimmedUrl = url.trim();
7+
8+
if (trimmedUrl.startsWith("/") || trimmedUrl.startsWith("./") || trimmedUrl.startsWith("../")) {
9+
return false;
10+
}
11+
12+
if (trimmedUrl.startsWith("#")) {
13+
return false;
14+
}
15+
16+
if (trimmedUrl.startsWith("mailto:") || trimmedUrl.startsWith("tel:")) {
17+
return true;
18+
}
19+
220
try {
3-
const urlObj = new URL(url);
4-
return urlObj.hostname !== window.location.hostname;
21+
const currentOrigin = window.location.origin;
22+
const linkUrl = new URL(trimmedUrl, currentOrigin);
23+
24+
return linkUrl.origin !== currentOrigin;
525
} catch {
6-
return false;
26+
return true;
727
}
828
};

web/src/utils/urlValidation.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,45 @@
1+
const DANGEROUS_PROTOCOLS = ["javascript:", "vbscript:", "file:", "about:", "blob:", "filesystem:"];
2+
3+
const ALLOWED_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
4+
5+
const ALLOWED_DATA_TYPES = ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"];
6+
7+
const isValidDataUri = (url: string): boolean => {
8+
const dataUriRegex = /^data:([^;,]+)(;base64)?,/i;
9+
const match = url.match(dataUriRegex);
10+
11+
if (!match) {
12+
return false;
13+
}
14+
15+
const mimeType = match[1].toLowerCase();
16+
return ALLOWED_DATA_TYPES.includes(mimeType);
17+
};
18+
119
export const isValidUrl = (url: string): boolean => {
20+
if (!url || typeof url !== "string") {
21+
return false;
22+
}
23+
24+
const trimmedUrl = url.trim().toLowerCase();
25+
26+
if (trimmedUrl.length === 0) {
27+
return false;
28+
}
29+
30+
if (trimmedUrl.startsWith("data:")) {
31+
return isValidDataUri(trimmedUrl);
32+
}
33+
34+
for (const protocol of DANGEROUS_PROTOCOLS) {
35+
if (trimmedUrl.startsWith(protocol)) {
36+
return false;
37+
}
38+
}
39+
240
try {
3-
new URL(url);
4-
return true;
41+
const urlObj = new URL(url);
42+
return ALLOWED_PROTOCOLS.includes(urlObj.protocol);
543
} catch {
644
return false;
745
}

0 commit comments

Comments
 (0)