Repository: spotify/backstage
File: packages/integration/src/azure/DefaultAzureDevOpsCredentialsProvider.ts (TypeScript)

Code before:
        return this.providers.get(`${url.host}/${parts[1]}`);
      }
    }

    return undefined;
  }

  private forAzureDevOpsOrganization(
    url: URL,
  ): AzureDevOpsCredentialsProvider | undefined {
    const parts = url.pathname.split('/').filter(part => part !== '');
    if (url.host === 'dev.azure.com' && parts.length > 0) {
      // url format: https://{host}/{organization}
      return this.providers.get(`${url.host}/${parts[0]}`);
    }

    return undefined;
  }

  private forVisualstudioOrganization(
    url: URL,
  ): AzureDevOpsCredentialsProvider | undefined {
    const parts = url.host.split('.');
    if (url.host.includes('visualstudio.com') && parts.length > 0) {
      // url format: https://{organization}.visualstudio.com
      return this.providers.get(`${url.host}/${parts[0]}`);
    }

    return undefined;
  }

  private forHost(url: URL): AzureDevOpsCredentialsProvider | undefined {
    return this.providers.get(url.host);
  }

  async getCredentials(opts: {
    url: string;
  }): Promise<AzureDevOpsCredentials | undefined> {
    const url = new URL(opts.url);
    const provider =
      this.forAzureDevOpsOrganization(url) ??
      this.forAzureDevOpsServerOrganization(url) ??
      this.forVisualstudioOrganization(url) ??
      this.forHost(url);

    if (provider === undefined) {
      return undefined;
    }

    return provider.getCredentials(opts);
  }

Review comment (security):
Reading through the code, as long as you don't specify `organizations` you should be able to simply do this:
```suggestion
      return this.providers.get(`${url.host}`);
```

This could be another argument to enforce this through the config format. Right now I'm not sure if the code will work for this configuration:
```yaml
host: 'org1.visualstudio.com',
credentials: [
 {
    personalAccessToken: 'pat'
 }
]
```

Code after:
        // url format: https://{host}/tfs/{organization}
        return this.providers.get(`${url.host}/${parts[1]}`);
      }
    }

    return undefined;
  }

  private forAzureDevOpsOrganization(
    url: URL,
  ): AzureDevOpsCredentialsProvider | undefined {
    const parts = url.pathname.split('/').filter(part => part !== '');
    if (url.host === 'dev.azure.com' && parts.length > 0) {
      // url format: https://{host}/{organization}
      return this.providers.get(`${url.host}/${parts[0]}`);
    }

    return undefined;
  }

  private forVisualStudioOrganization(
    url: URL,
  ): AzureDevOpsCredentialsProvider | undefined {
    const parts = url.host.split('.');
    if (isVisualStudioDomain(url.origin) && parts.length > 0) {
      return this.providers.get(url.host);
    }

    return undefined;
  }

  private forHost(url: URL): AzureDevOpsCredentialsProvider | undefined {
    return this.providers.get(url.host);
  }

  async getCredentials(opts: {
    url: string;
  }): Promise<AzureDevOpsCredentials | undefined> {
    const url = new URL(opts.url);
    const provider =
      this.forAzureDevOpsOrganization(url) ??
      this.forAzureDevOpsServerOrganization(url) ??
      this.forVisualStudioOrganization(url) ??
      this.forHost(url);

    if (provider === undefined) {
      return undefined;
    }

    return provider.getCredentials(opts);
  }