chromium/tools/binary_size/libsupersize/viewer/static/auth.js

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';


/** @type {(a: TokenClient) => void} Resolve function of g_authScriptPromise. */
let g_onAuthScriptLoaded = null;
/** @type {Promise<TokenClient>} Resolves when GIS is loaded. */
const g_authScriptPromise = new Promise((resolve, reject) => {
  g_onAuthScriptLoaded = resolve;
});

/** @type {(a: string) => void} Resolve function of g_authTokenPromise. */
let g_onTokenReceived = null;
/** @type {Promise<string>} Resolves when access token is received. */
const g_authTokenPromise = new Promise((resolve, reject) => {
  g_onTokenReceived = resolve;
});

/** @type {boolean} Used to ensure the auth pipeline is only setup once. */
let g_authFetchCalled = false;

/** @return {Promise<*>} */
async function initClient() {
  let tokenClient = google.accounts.oauth2.initTokenClient({
    client_id: AUTH_CLIENT_ID,
    scope: AUTH_SCOPE,
    callback: '',  // defined at request time in await/promise scope.
  });
  g_onAuthScriptLoaded(tokenClient);
}

/** @return {Promise<void>} */
async function getToken() {
  let tokenClient = await g_authScriptPromise;
  try {
    tokenClient.callback = (resp) => {
      if (resp.error === undefined) {
        g_onTokenReceived(resp.access_token);
      }
    };
    tokenClient.requestAccessToken();
  } catch (err) {
    console.error(err)
  }
}

/** @return {Promise<void>} */
async function doAuthFetch() {
  // TODO(mheikal): cache access token in localstorage and check if expired here
  // and return cached token.

  // Show a "Please sign in" dialog.
  toggleSigninModal(true /*show*/);
  const btnSignin = g_el.divSigninModal.querySelector('button.signin');
  btnSignin.addEventListener('click', getToken);

  // Only hide the dialog once we have the token.
  await g_authTokenPromise;
  toggleSigninModal(false /*show*/);
}

/** @return {Promise<?string>} */
async function fetchAccessToken() {
  if (!g_authFetchCalled) {
    doAuthFetch();
    g_authFetchCalled = true;
  }
  return await g_authTokenPromise;
}

/** @param {boolean} show */
function toggleSigninModal(show) {
  g_el.divSigninModal.style.display = show ? '' : 'none';
}

/**
 * @param {!Array<!URL>} urlsToLoad
 * @return {boolean}
 */
function requiresAuthentication(urlsToLoad) {
  for (const url of urlsToLoad) {
    // Files from ocalhost, public trybot, and one-offs don't need auth.
    if (url.hostname === 'localhost')
      continue;
    if (url.pathname.startsWith(
            '/chromium-binary-size-trybot-results/android-binary-size/')) {
      continue;
    }
    if (url.pathname.indexOf('/oneoffs/') >= 0)
      continue;
    // Assume everything else requires auth.
    return true;
  }
  return false;
}