<NME> special_protocol_request.ts
<BEF> /**
 * @license
 * Copyright 2020 Google Inc.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {CredentialsManager, MaybeOptionalCredentialsProvider} from 'neuroglancer/credentials_provider';
import {fetchWithOAuth2Credentials} from 'neuroglancer/credentials_provider/oauth2';
import {CancellationToken, uncancelableToken} from 'neuroglancer/util/cancellation';
import {parseUrl, ResponseTransform} from 'neuroglancer/util/http_request';
import {getRandomHexString} from 'neuroglancer/util/random';
import {cancellableFetchS3Ok} from 'neuroglancer/util/s3';
export type SpecialProtocolCredentialsProvider =
  MaybeOptionalCredentialsProvider<SpecialProtocolCredentials>;

function getNgauthCredentialsProvider(
    credentialsManager: CredentialsManager, serverUrl: string,
    path: string): SpecialProtocolCredentialsProvider {
            credentialsManager.getCredentialsProvider('gcs', {bucket: u.host}) :
            undefined,
        url,
      };
    case 'gs+ngauth+http':
      return {
        credentialsProvider:
            getNgauthCredentialsProvider(credentialsManager, `http://${u.host}`, u.path),
        url: 'gs:/' + u.path,
      };
    case 'gs+ngauth+https':
      return {
        credentialsProvider:
            getNgauthCredentialsProvider(credentialsManager, `https://${u.host}`, u.path),
        url: 'gs:/' + u.path,
      };
    case 'gs+xml+ngauth+http':
      return {
        credentialsProvider:
            getNgauthCredentialsProvider(credentialsManager, `http://${u.host}`, u.path),
        url: 'gs+xml:/' + u.path,
      };
    case 'gs+xml+ngauth+https':
      return {
        credentialsProvider:
            getNgauthCredentialsProvider(credentialsManager, `https://${u.host}`, u.path),
        url: 'gs+xml:/' + u.path,
      };
    case 'middleauth+https':
      url = url.substr('middleauth+'.length);
      return {
        credentialsProvider: getMiddleAuthCredentialsProvider(credentialsManager, url),
        url: url,
      };
    case 's3':
      return {
        credentialsProvider: undefined,
        url,
        credentialsProvider: getNgauthCredentialsProvider(credentialsManager, `https://${u.host}`, u.path),
        url: 'gs+xml:/' + u.path,
      };
    default:
      return {
        credentialsProvider: undefined,
    cancellationToken: CancellationToken = uncancelableToken): Promise<T> {
  const u = parseUrl(url);
  switch (u.protocol) {
    case 'gs':
      // Include random query string parameter (ignored by GCS) to bypass GCS cache and ensure a
      // cached response is never used.
      //
      // This addresses two issues related to GCS:
      //
      // 1. GCS fails to send an updated `Access-Control-Allow-Origin` header in 304 responses to
      //    cache revalidation requests.
      //
      //    https://bugs.chromium.org/p/chromium/issues/detail?id=1214563#c2
      //
      //    The random query string parameter ensures cached responses are never used.
      //
      //    Note: This issue does not apply to gs+xml because with the XML API, the
      //    Access-Control-Allow-Origin response header does not vary with the Origin.
      //
      // 2. If the object does not prohibit caching (e.g. public bucket and default `cache-control`
      //    metadata value), GCS may return stale responses.
      //
      return fetchWithOAuth2Credentials(
          credentialsProvider,
          `https://www.googleapis.com/storage/v1/b/${u.host}/o/` +
              `${encodeURIComponent(u.path.substring(1))}?alt=media` +
              `&neuroglancer=${getRandomHexString()}`,
          init, transformResponse, cancellationToken);
    case 'gs+xml':
      return fetchWithOAuth2Credentials(
          credentialsProvider,
          `https://storage.googleapis.com/${u.host}${u.path}` +
              `?neuroglancer=${getRandomHexString()}`,
          init, transformResponse, cancellationToken);
    case 's3':
      return cancellableFetchS3Ok(u.host, u.path, init, transformResponse, cancellationToken);
    default:
      return fetchWithOAuth2Credentials(
          credentialsProvider, url, init, transformResponse, cancellationToken);
  }
}

<MSG> re-implemented middleauth using CredentialsProvider

<DFF> @@ -23,6 +23,30 @@ export type SpecialProtocolCredentials = OAuth2Credentials|undefined;
 export type SpecialProtocolCredentialsProvider =
   MaybeOptionalCredentialsProvider<SpecialProtocolCredentials>;
 
+function getMiddleAuthCredentialsProvider(
+    credentialsManager: CredentialsManager, url: string): SpecialProtocolCredentialsProvider {
+  // TODO: will add endpoint to lookup auth server using serverUrl
+  function getAuthURL(serverUrl: string) {
+    const auth_url_map = {
+      'https://globalv1.flywire-daf.com': 'https://globalv1.daf-apis.com/auth',
+      'https://globalv1.daf-apis.com': 'https://globalv1.daf-apis.com/auth',
+      'https://authsl1.middleauth.com': 'https://authsl1.middleauth.com/auth'
+    }
+
+    for (const [partialUrl, authURL] of Object.entries(auth_url_map)) {
+      if (serverUrl.startsWith(partialUrl)) {
+        return authURL;
+      }
+    }
+
+    return undefined;
+  }
+
+  const authURL = getAuthURL(url);
+  return credentialsManager.getCredentialsProvider(
+    'middleauth', authURL);
+}
+
 function getNgauthCredentialsProvider(
     credentialsManager: CredentialsManager, serverUrl: string,
     path: string): SpecialProtocolCredentialsProvider {
@@ -67,6 +91,12 @@ export function parseSpecialUrl(url: string, credentialsManager: CredentialsMana
         credentialsProvider: getNgauthCredentialsProvider(credentialsManager, `https://${u.host}`, u.path),
         url: 'gs+xml:/' + u.path,
       };
+      case 'middleauth+https':
+        url = url.substr('middleauth+'.length);
+        return {
+          credentialsProvider: getMiddleAuthCredentialsProvider(credentialsManager, url),
+          url: url,
+        };
     default:
       return {
         credentialsProvider: undefined,

re-implemented middleauth using CredentialsProvider