Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5145cc0

Browse files
committed
chore: parse app status link
No actual exploit here as far as I can tell, but doing a string checkwithout parsing was flagged by a scanner.
1 parent7849794 commit5145cc0

File tree

3 files changed

+139
-46
lines changed

3 files changed

+139
-46
lines changed

‎site/src/pages/TaskPage/TaskSidebar.tsx‎

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
importGitHubfrom"@mui/icons-material/GitHub";
21
import{Button}from"components/Button/Button";
32
import{
43
DropdownMenu,
@@ -14,21 +13,15 @@ import {
1413
TooltipProvider,
1514
TooltipTrigger,
1615
}from"components/Tooltip/Tooltip";
17-
import{
18-
ArrowLeftIcon,
19-
BugIcon,
20-
EllipsisVerticalIcon,
21-
ExternalLinkIcon,
22-
GitPullRequestArrowIcon,
23-
}from"lucide-react";
16+
import{ArrowLeftIcon,EllipsisVerticalIcon}from"lucide-react";
2417
import{AppStatusStateIcon}from"modules/apps/AppStatusStateIcon";
2518
importtype{Task}from"modules/tasks/tasks";
2619
importtype{FC}from"react";
2720
import{LinkasRouterLink}from"react-router-dom";
2821
import{cn}from"utils/cn";
2922
import{timeFrom}from"utils/time";
30-
import{truncateURI}from"utils/uri";
3123
import{TaskAppIFrame}from"./TaskAppIframe";
24+
import{TaskStatusLink}from"./TaskStatusLink";
3225
import{AI_APP_CHAT_SLUG,AI_APP_CHAT_URL_PATHNAME}from"./constants";
3326

3427
typeTaskSidebarProps={
@@ -201,40 +194,3 @@ const TaskStatuses: FC<TaskStatusesProps> = ({ task }) => {
201194
<Spinnerloading/>
202195
);
203196
};
204-
205-
typeTaskStatusLinkProps={
206-
uri:string;
207-
};
208-
209-
constTaskStatusLink:FC<TaskStatusLinkProps>=({ uri})=>{
210-
leticon=<ExternalLinkIcon/>;
211-
letlabel=truncateURI(uri);
212-
213-
if(uri.startsWith("https://github.com")){
214-
constissueNumber=uri.split("/").pop();
215-
const[org,repo]=uri.split("/").slice(3,5);
216-
constprefix=`${org}/${repo}`;
217-
218-
if(uri.includes("pull/")){
219-
icon=<GitPullRequestArrowIcon/>;
220-
label=issueNumber
221-
?`${prefix}#${issueNumber}`
222-
:`${prefix} Pull Request`;
223-
}elseif(uri.includes("issues/")){
224-
icon=<BugIcon/>;
225-
label=issueNumber ?`${prefix}#${issueNumber}` :`${prefix} Issue`;
226-
}else{
227-
icon=<GitHub/>;
228-
label=`${org}/${repo}`;
229-
}
230-
}
231-
232-
return(
233-
<ButtonasChildvariant="outline"size="sm"className="min-w-0">
234-
<ahref={uri}target="_blank"rel="noreferrer">
235-
{icon}
236-
{label}
237-
</a>
238-
</Button>
239-
);
240-
};
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
importtype{Meta,StoryObj}from"@storybook/react";
2+
import{TaskStatusLink}from"./TaskStatusLink";
3+
4+
constmeta:Meta<typeofTaskStatusLink>={
5+
title:"pages/TaskPage/TaskStatusLink",
6+
component:TaskStatusLink,
7+
// Add a wrapper to test truncation.
8+
decorators:[
9+
(Story)=>(
10+
<divstyle={{display:"flex",width:"200px"}}>
11+
<Story/>
12+
</div>
13+
),
14+
],
15+
};
16+
17+
exportdefaultmeta;
18+
typeStory=StoryObj<typeofTaskStatusLink>;
19+
20+
exportconstGithubPRNumber:Story={
21+
args:{
22+
uri:"https://github.com/org/repo/pull/1234",
23+
},
24+
};
25+
26+
exportconstGitHubPRNoNumber:Story={
27+
args:{
28+
uri:"https://github.com/org/repo/pull",
29+
},
30+
};
31+
32+
exportconstGithubIssueNumber:Story={
33+
args:{
34+
uri:"https://github.com/org/repo/issues/4321",
35+
},
36+
};
37+
38+
exportconstGithubIssueNoNumber:Story={
39+
args:{
40+
uri:"https://github.com/org/repo/issues",
41+
},
42+
};
43+
44+
exportconstGithubOrgRepo:Story={
45+
args:{
46+
uri:"https://github.com/org/repo",
47+
},
48+
};
49+
50+
exportconstGithubOrg:Story={
51+
args:{
52+
uri:"https://github.com/org",
53+
},
54+
};
55+
56+
exportconstGithub:Story={
57+
args:{
58+
uri:"https://github.com",
59+
},
60+
};
61+
62+
exportconstFile:Story={
63+
args:{
64+
uri:"file:///path/to/file",
65+
},
66+
};
67+
68+
exportconstLong:Story={
69+
args:{
70+
uri:"https://dev.coder.com/this-is-a/long-url/to-test/how-the-truncation/looks",
71+
},
72+
};
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
importGitHubfrom"@mui/icons-material/GitHub";
2+
import{Button}from"components/Button/Button";
3+
import{
4+
BugIcon,
5+
ExternalLinkIcon,
6+
GitPullRequestArrowIcon,
7+
}from"lucide-react";
8+
importtype{FC}from"react";
9+
10+
exporttypeTaskStatusLinkProps={
11+
uri:string;
12+
};
13+
14+
exportconstTaskStatusLink:FC<TaskStatusLinkProps>=({ uri})=>{
15+
leticon=<ExternalLinkIcon/>;
16+
letlabel=uri;
17+
18+
try{
19+
constparsed=newURL(uri);
20+
switch(parsed.protocol){
21+
// For file URIs, strip off the `file://`.
22+
case"file:":
23+
label=uri.replace(/^file:\/\//,"");
24+
break;
25+
case"http:":
26+
case"https:":
27+
// For GitHub URIs, use a short representation.
28+
if(parsed.host==="github.com"){
29+
const[_,org,repo,type,number]=parsed.pathname.split("/");
30+
switch(type){
31+
case"pull":
32+
icon=<GitPullRequestArrowIcon/>;
33+
label=number
34+
?`${org}/${repo}#${number}`
35+
:`${org}/${repo} pull request`;
36+
break;
37+
case"issues":
38+
icon=<BugIcon/>;
39+
label=number
40+
?`${org}/${repo}#${number}`
41+
:`${org}/${repo} issue`;
42+
break;
43+
default:
44+
icon=<GitHub/>;
45+
if(org&&repo){
46+
label=`${org}/${repo}`;
47+
}
48+
break;
49+
}
50+
}
51+
break;
52+
}
53+
}catch(error){
54+
// Invalid URL, probably.
55+
}
56+
57+
return(
58+
<ButtonasChildvariant="outline"size="sm"className="min-w-0">
59+
<ahref={uri}target="_blank"rel="noreferrer">
60+
{icon}
61+
<spanclassName="truncate">{label}</span>
62+
</a>
63+
</Button>
64+
);
65+
};

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp