Repository navigation
Expand file tree
/
Copy pathgithubLink.ts
More file actions
51 lines (47 loc) · 2.24 KB
/
Copy pathgithubLink.ts
File metadata and controls
51 lines (47 loc) · 2.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
export function safeGithubLink(link?: string): string | undefined {
try {
const url = new URL(link ?? '');
return url.protocol === 'https:' && url.hostname === 'github.com'
&& (url.pathname === '/settings/personal-access-tokens' || url.pathname.startsWith('/settings/personal-access-tokens/'))
? url.toString() : undefined;
} catch {
return undefined;
}
}
/** Repository Actions Secret settings only; no token or arbitrary navigation parameters. */
export function repositorySecretSettingsLink(repository?: string): string | undefined {
return repository && /^[A-Za-z0-9-]{1,39}\/(?!\.{1,2}$)[A-Za-z0-9._-]{1,100}$/u.test(repository)
? `https://github.com/${repository}/settings/secrets/actions` : undefined;
}
/** Only the immutable run-detail route is an allowed CI evidence destination. */
export function safeGithubRunLink(link?: string): string | undefined {
try {
const url = new URL(link ?? '');
return url.protocol === 'https:' && url.hostname === 'github.com'
&& !url.username && !url.password && !url.search && !url.hash
&& /^\/[A-Za-z0-9-]{1,39}\/[A-Za-z0-9._-]{1,100}\/actions\/runs\/[1-9][0-9]*$/u.test(url.pathname)
? url.toString() : undefined;
} catch {
return undefined;
}
}
/** Exact repository ruleset page used only for verified required-check evidence. */
export function safeGithubRulesetLink(link?: string): string | undefined {
try {
const url = new URL(link ?? '');
return url.protocol === 'https:' && url.hostname === 'github.com'
&& !url.username && !url.password && !url.search && !url.hash
&& /^\/[A-Za-z0-9-]{1,39}\/[A-Za-z0-9._-]{1,100}\/rules\/[1-9][0-9]*$/u.test(url.pathname)
? url.toString() : undefined;
} catch { return undefined; }
}
/** Existing Project detail pages only; do not trust provider-supplied arbitrary GitHub URLs. */
export function safeGithubProjectLink(link?: string): string | undefined {
try {
const url = new URL(link ?? '');
return url.protocol === 'https:' && url.hostname === 'github.com'
&& !url.username && !url.password && !url.search && !url.hash
&& /^\/(?:orgs|users)\/[A-Za-z0-9-]{1,39}\/projects\/[1-9][0-9]*$/u.test(url.pathname)
? url.toString() : undefined;
} catch { return undefined; }
}