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