chrome.identity.getAuthTokenを使用した拡張でOAuth API Verificationを通そうとすると詰む。

2019/09/09 追記

OAuth API Verification通りました。(私の場合ですと承認まで6営業日かかりました。ご参考までに。)
やり取り終わらないんじゃないかと思っていたので安心しました。
(追記終わり)


詰んだ。

背景

Googleから「GoogleのAPIを使用するアプリの承認を通せ」という内容のメールが来ていて、ついでなので、Right-Click to Calendarが使用するAPIのスコープを絞った上でレビューを依頼することにしました。なお、承認までのやり取りは全部英語で行う必要があります。
以下はGoogleから受け取ったメールの一部引用です。

Hello Google API Developer,

We’re writing to let you know that as part of ongoing and proactive security measures to protect users from deceptive apps, we now require apps which access user data via sensitive API scopes to be verified to ensure compliance with the Google API User Data Policy. We are proactively reaching out to you to help ensure the least disruption to your app(s).

Although you may have recently submitted your app for verification, you must also submit for the sensitive scopes listed below which have not previously been verified. Please submit your app(s) for sensitive scope verification by October 21, 2019.

ちなみに、承認を通さないとOAuth認可時に以下の感じで警告が出ます。(まだ承認が通ってないので、Right-Click to Calendarでは今も表示されます。承認通ったので表示されなくなりました。)

OAuth認可時に警告が出る
OAuth認可時に警告が出る

OAuth API Verification FAQ - Google Cloud Platform Console ヘルプを参照すると、検証プロセスの中で、「OAuth認可までの手順」と「OAuth client ID」が撮影された動画をYouTubeにアップロードする必要があります。通常OAuth client IDはOAuth認可用のURLの中に含まれるため、それをアドレスバーで表示すれば問題ありません。以下は、ヘルプの該当部分の引用です。

Please include a YouTube link to a demo video demonstrating the OAuth grant process by users and explaining, in detail, the usage of sensitive and restricted scopes within the app’s functionality for each OAuth client belonging to the project.
Note that the video should clearly show the app’s details such as the app name, OAuth client ID, and so on. For multiple client IDs, the demo video should show usage of sensitive and restricted scopes on each client.

ヘルプの中では「アドレスバーに表示しろ」とは明記されていませんが、私がレビューを受けたときはアドレスバーに表示しろと指示があって、別の方法は認めてもらえなかったので、アドレスバーを撮影しておいたほうが無難だと思います。以下は私がレビューのときに受けた指示です。

In order to continue with the verification process, you’ll need to create and provide a link to a YouTube video that shows how you’ll use the data you access using OAuth scopes. Specifically, the demo video should detail, in English:

  1. How to log into your project (ensuring that the URL bar with the client ID is clearly visible)
  2. How to request an OAuth token (OAuth Consent Screen/Permissions Page)
  3. How your project’s functionality utilizes the requested scopes:
    https://www.googleapis.com/auth/calendar.events
    https://www.googleapis.com/auth/calendar.readonly

問題点

chrome.identity.getAuthTokenを使用した場合、Identity API Scope Approval UIという拡張機能が呼び出されて、GoogleへのログインとOAuth認可が開始されるのですが、このプロセスに問題があります。Identity API Scope Approval UIが表示する認証画面はchrome.app.window.createで生成され、そのウインドウの中にあるwebviewタグの中に描画されるのですが、chrome.app.windowの仕様上アドレスバーを表示することができないのと、仮に表示できたとしても、認証用のURLをアドレスバーに出すことが出来ません。(なんでこんなクソみたいな作りなのかは知らない。)
Identity API Scope Approval UIの実際のソースは以下です。
chromium/chrome/browser/resources/identity_scope_approval_dialog at 79.0.3906.1 · chromium/chromium

そのため、上記の説明を含めてレビュワーに「Chromeの仕様上、アドレスバーにOAuth認可用のURLを表示することができない。拡張をDLしてmanifest.jsonを確認してほしい。それが無理なら別の審査方法を提示してほしい」と(英語で)説明したのですが、私の英語力が終わってるせいか、もしくはレビュワーガチャに失敗したのか、「アドレスバーにOAuth Client IDを表示しろ」の一点張りで全く解決しませんでした。
このやり取りですでに4営業日以上消費していて疲れたのと、アプリを改変するのも嫌なので、諦めてIdentity API Scope Approval UI(identity_scope_approval_dialog)の挙動を今回の要求仕様を満たすように変更して、動画を取り直すことにしました。

identity_scope_approval_dialogの修正方法

identity_scope_approval_dialogはChromeのインストール先ディレクトリのresources.pakに含まれています。
私の環境だと C:\Program Files\Google\Chrome\Application\<Chromeのバージョン番号> の中にありました。

まずresources.pakをunpackします。pakをunpack/packできるツールを公開してくださってる方がいるので、それを使います。
myfreeer/chrome-pak-customizer: a simple command-line tool to pack and unpack pak files in chrome or chromium-based browser

resources.pakをunpackすると、タイトルが数字の羅列になっているファイルが大量に出てきます。identity_scope_approval_dialogもファイル名が変わってるので、”loadAuthUrlAndShowWindow” あたりでgrepして該当ファイルを探します。

background.jsに該当するファイルの”showAuthDialog”メソッドを以下のように修正します。

function showAuthDialog(key, url, mode) {
  /* const options =
      {frame: 'chrome', id: key, minWidth: 1024, minHeight: 768, hidden: true};
  chrome.app.window.create(
      'scope_approval_dialog.html', options, function(win) {
        win.contentWindow.addEventListener('load', function(event) {
          let windowParam;
          if (mode == 'interactive') {
            windowParam = win;
          }
          win.contentWindow.loadAuthUrlAndShowWindow(url, windowParam);
        });
      }); */
  window.open(url);
}

chrome.app.window.create処理を無効化して、認可用のURLをそのまま新規ウインドウで開くようにしました。

修正したresourcesをpackして、修正前のresources.pakに差し替えます。

修正前と修正後の挙動の比較

修正前
修正前

アドレスバーがないので、どこにアクセスしているかわからない状態になっています。

修正後
修正後

別タブで認可用のURLが表示されるようになりました。

余談

identity_scope_approval_dialogが表示するwebviewをデバッグしたい場合、 chrome://inspect/#apps からデバッグ可能です。私は使いませんでした。

これでレビュー弾かれたらメールにFxxkとか書いちゃいそうなくらいにはやり取りに疲弊してるので、はやく承認通したいです…。(5営業日でレビュー完了できなかった。)それかレビュワー別の人に変わってほしいですね…全然こっちのメール読んでくれないので完全にガチャ外した感がある。相手、人じゃなくてAIかもしれないけど…。