Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/platform/extensionManagement/common/configRemotes.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { URI } from '../../../base/common/uri.js';
7
8
const SshProtocolMatcher = /^([^@:]+@)?([^:]+):/;
9
const SshUrlMatcher = /^([^@:]+@)?([^:]+):(.+)$/;
10
const AuthorityMatcher = /^([^@]+@)?([^:]+)(:\d+)?$/;
11
const SecondLevelDomainMatcher = /([^@:.]+\.[^@:.]+)(:\d+)?$/;
12
const RemoteMatcher = /^\s*url\s*=\s*(.+\S)\s*$/mg;
13
const AnyButDot = /[^.]/g;
14
15
export const AllowedSecondLevelDomains = [
16
'github.com',
17
'bitbucket.org',
18
'visualstudio.com',
19
'gitlab.com',
20
'heroku.com',
21
'azurewebsites.net',
22
'ibm.com',
23
'amazon.com',
24
'amazonaws.com',
25
'cloudapp.net',
26
'rhcloud.com',
27
'google.com',
28
'azure.com'
29
];
30
31
function stripLowLevelDomains(domain: string): string | null {
32
const match = domain.match(SecondLevelDomainMatcher);
33
return match ? match[1] : null;
34
}
35
36
function extractDomain(url: string): string | null {
37
if (url.indexOf('://') === -1) {
38
const match = url.match(SshProtocolMatcher);
39
if (match) {
40
return stripLowLevelDomains(match[2]);
41
} else {
42
return null;
43
}
44
}
45
try {
46
const uri = URI.parse(url);
47
if (uri.authority) {
48
return stripLowLevelDomains(uri.authority);
49
}
50
} catch (e) {
51
// ignore invalid URIs
52
}
53
return null;
54
}
55
56
export function getDomainsOfRemotes(text: string, allowedDomains: readonly string[]): string[] {
57
const domains = new Set<string>();
58
let match: RegExpExecArray | null;
59
while (match = RemoteMatcher.exec(text)) {
60
const domain = extractDomain(match[1]);
61
if (domain) {
62
domains.add(domain);
63
}
64
}
65
66
const allowedDomainsSet = new Set(allowedDomains);
67
return Array.from(domains)
68
.map(key => allowedDomainsSet.has(key) ? key : key.replace(AnyButDot, 'a'));
69
}
70
71
function stripPort(authority: string): string | null {
72
const match = authority.match(AuthorityMatcher);
73
return match ? match[2] : null;
74
}
75
76
function normalizeRemote(host: string | null, path: string, stripEndingDotGit: boolean): string | null {
77
if (host && path) {
78
if (stripEndingDotGit && path.endsWith('.git')) {
79
path = path.substr(0, path.length - 4);
80
}
81
return (path.indexOf('/') === 0) ? `${host}${path}` : `${host}/${path}`;
82
}
83
return null;
84
}
85
86
function extractRemote(url: string, stripEndingDotGit: boolean): string | null {
87
if (url.indexOf('://') === -1) {
88
const match = url.match(SshUrlMatcher);
89
if (match) {
90
return normalizeRemote(match[2], match[3], stripEndingDotGit);
91
}
92
}
93
try {
94
const uri = URI.parse(url);
95
if (uri.authority) {
96
return normalizeRemote(stripPort(uri.authority), uri.path, stripEndingDotGit);
97
}
98
} catch (e) {
99
// ignore invalid URIs
100
}
101
return null;
102
}
103
104
export function getRemotes(text: string, stripEndingDotGit: boolean = false): string[] {
105
const remotes: string[] = [];
106
let match: RegExpExecArray | null;
107
while (match = RemoteMatcher.exec(text)) {
108
const remote = extractRemote(match[1], stripEndingDotGit);
109
if (remote) {
110
remotes.push(remote);
111
}
112
}
113
return remotes;
114
}
115
116