GitHubでアカウント名を別の名前で表示できるChrome拡張を作った。

2019/09/30 追記

コメントくださった方へ:
PRのレビュワーサジェストに対応 · retrorocket/github-name-alias-chrome-extension@68b5dec
PR内でのレビュワーのサジェストに対応しました。コードのリファクタリングが必要なのでストア登録はもう少しまってください。


タイトルつけるの難しいなこれ。仕事でGitHub.comを使うにあたって、すでにフリーアカウントを所持している人はそのアカウントで仕事をすることになるのですが、本名に1ミリもかすってないアカウントだと誰が誰だかわからないって話がありました。個人的には人の本名を覚えるよりも、本名に1ミリもかすってないアカウントのほうが覚えやすいのですが、確かにそういう意見もあるよなぁと思ったのでChrome拡張でどうにかしました。正確に言うと、すごい適当に作りすぎてコードが読めるレベルじゃないのと、GitHubのjsとか色々フックするのが難しくてまだ全然どうにかなってないけど、最低限どうにかしました。

作ったもの

retrorocket/github-name-alias-chrome-extension: GitHubで名前にエイリアスを設定するためのChrome拡張です

オプションページで設定してから動かしてください。
全然どうにかなってない箇所が多いのと、コードの可読性が最悪で一回きれいにしたいので、ストアへの公開は(今回は)見送っています。

使うとどうなるか

例えばretrorocketの本名がハム太郎だったとして、retrorocketの本名を知っている人がhamutaroでサジェストしたい場合

拡張を使う前

拡張を使う前

表示がハム太郎に置き換わった上で、hamutaroでサジェストできるようになります。

拡張を使った後

拡張を使った後

(「github」が「habutaro」で候補に出るようにしてるので、スクショには「github」も出てきてます)

うまくうごかないところ

さすがにアカウント名が表示される箇所を全部置換するのはやりたくないのでやりませんでした。(PR発行とか)SPAになってる箇所があるので、一回DOMが動的に書き換わってもcontent scriptが再度動いてくれないです。仕方ないのでbodyをクリックしたときに、アカウント名の再描画とサジェスト部分の再設定が走るようにしています。(MutationObserverでDOMの書き換えを検知する手もありますが、監視しすぎると処理が重くなるので今回は見送っています。)
あとサジェスト関連の動きがだいぶ怪しいです。ほぼ期待通り動かないので改善の余地ありです。GitHubのサジェストツールの上で拡張を動作させたかったのですが、GitHub側のjsの動作にフックできなかったので一部自分で実装しています。(GitHubのサジェストツールだと矢印キーで候補の選択ができますが、そこまで頑張れなかった。)
GitHubのようなtextareaの補完機能を実装する - カーソル位置の取得 - Qiita
自分でそれっぽいの書いてて思いましたが、GitHubのサジェストは大変に優秀ですね…。すごい…。

ためしたいところ

GitHubは候補の一覧をそれ用のAPIから取得しているので、このAPIのレスポンスボディを改変できればきれいに実装できるのですが、chrome.webRequestではレスポンスボディの改変はできないです。取得したレスポンスボディに自前の候補をくっつけられるような実装ができないかは試したいですね。

こんなんすぐ実装できるやんけと思ってたけど全然だめでした。

chrome.identity.launchWebAuthFlowでChromeの拡張からTwitterのOAuth認証・認可をする。

Chromeの拡張からTwitterを使いたかったのですが、認証・認可に使ってたライブラリが結局全部使えなくなったので、chrome.identity.launchWebAuthFlowで実装することにしました。

ソースコードが長いのと、使い回しができるのでGitHubにコミットしておきました。 options.js が本体です。
retrorocket/chrome-extension-twitter-oauth-sample: TwitterのOAuth1.0認証認可をChrome拡張から実施するサンプル
シグネチャをつくる部分はさすがにライブラリがあるので、安心と信頼の johan/oauth-js: A mirror of the svn http://oauth.googlecode.com/svn/code/javascript/ (sub-)repository. を使用しています。差し替えできる処理なので、好きなライブラリを使っても問題ないです。

chrome.identity.launchWebAuthFlowは非同期なので、呼び出し処理をpromiseとして定義しておかないとrequest tokenの取得が終わる前に勝手に呼び出されて認可に失敗します。ここはほんとに原因がわからなくて詰みかけました。
launchWebAuthFlow、仕様的にもOAuth 2.0向けのAPIなのに無理やりつかうのも微妙なので、Twitterは早くApplication-only authentication以外をOAuth 2.0に対応させてほしいです。

久々にOAuth周りのドキュメントとか仕様とかを読んだのですが、めちゃくちゃ忘れてるところが多かったので実装してよかったと思いました。
あと、Chromeの拡張にConsumer keyとsecret埋めこんだ場合、アプリのソースを覗かれるとkeyとsecretがバレますが、Callback URLの仕様が変わってホワイトリスト形式になり、詐称も難しくなったので、特に問題ないと思っています。

GitHubのアカウントを仕事とプライベートで同一にしたときのメリットとデメリット。

ついにギフハブと向き合わなければいけないときが来てしまった。

表題の件について、詳細は以下のブログにまとまっています。
全社的に会社用GitHubアカウントを廃止した件 - ZOZO Technologies TECH BLOG
github.comのアカウントは仕事用と私用で分ける方がいいの? - Islands in the byte stream

GitHub(.comのほう)は規約によりフリーアカウントを複数持てないので、仕事でフリーアカウントを使いたいなら、プライベートのフリーアカウントを仕事でも使うことになります。それなら、アカウントを同一にしたときのメリットとデメリットってなんだろう、と思ったのでメモしておきました。なお、この記事は飽くまでメモであり、ZOZOのブログのはてぶコメント等にも似たようなことが書いてあるので、見るならそちらのほうをおすすめします。

メリット

~こともある、がすべてのリストの末尾に付与されます。
GitHubのアカウントを公開してる人は、それに紐づくSNSやブログのアカウントも公開することが多いため、その前提で書いています。(デメリットも同様)

  • 社外の活動を社内にアピールできる
    • こういうOSSにコントリビュートしてます、とかこういうアプリを作ってます、というのがわかりやすい。
    • OSSへのコントリビュートが社内で推奨されている、あるいは業務として行えるなら、アカウントを分ける理由がない
  • 主観的ではなく、客観的なスキルセットを測れる(測ってもらえる)
    • 自分ではxxx(任意の言語/技術)があまりできないと思っていても、業務内容的には十分なスキルセットだったりすることもあったりする。そういう人が新しいことに挑戦できるきっかけが生まれるかもしれない。
  • 興味を持っているOSSを共有できる
    • 他の人がどんなOSSにスターをつけてるのか見るのが好きなので、(どちらかというと、自分のスターを公開したいのではなく)他人のスターが見たい
  • 所属するOrganizationのイメージアップに繋がる
    • 技術力めちゃつよな人が技術力めちゃつよなことしてたらそれだけでイメージが良くなるし、こういうエンジニアが活動できるところっていいなと思う。

デメリット

  • 社内の人にインターネット上での自分を特定される
    • つらい。
  • セキュリティ面(私物PCの盗難等)においてリスクがある
    • ZOZOのブログ参照
  • 所属するOrganizationのイメージダウンに繋がる危険性がある
    • よく「投稿内容は私個人の意見であり、所属企業・部門見解を代表するものではありません。」ってあるけど、切り離すのは難しいよなぁと思う。
    • Organization隠せるってどこかで見たけど、隠せないっていう説もあってよくわからない。
  • 自分が燃えると所属するOrganizationも巻き込んで延焼する
    • 燃えるような内容を書くべきではない、というのは当然として。インターネット上で何かする限り誰もが燃える可能性があると思っているので、起こってしまった場合に周りに迷惑をかけずにどうにかしたい。
    • これが私にとって一番避けたい事象なので、Organization隠させてくれ。頼む。
  • 技術力ふつうを装っていたが実は技術力めちゃつよであることがばれて仕事量がむちゃくちゃ増える
    • 自分のことではないが、そういうレアケースを過去一度だけ見た。とにかくかわいそうだったが本人がどう思ったかは知らない。
  • メリットを受けられるような技術力を持ち得ない場合、デメリットしかない
    • ああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ

書いててつらかった。
個人的な結論としてはOrganizationが隠せるなら許容できるけど、隠せないなら自分のアカウントか社内のアカウントをProにするしかないなって思いました。
あと、社内のProアカウントの支払いってみんなどうしてるんだろう。自分で立替してるの?

追記(2019/09/14)

Organization隠せました。よかった。
Publicizing or hiding organization membership - GitHub Help

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 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 (x86)\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かもしれないけど…。

殲滅t.coを6年ぶりくらいに更新しました。

殲滅t.co - Chrome ウェブストア
twitterのUIがどんどん改悪されていく…。

kill-tco/script.js at master · retrorocket/kill-tco · GitHub
これ、もはや拡張の意味があるのかわからない感じのコードになりましたね…。twitterカードとか、プロフィール内のリンクは復元後のURLが取得できないので諦めました。