Supabaseでメールアドレス変更時の確認リンククリック状況を判別する方法

supabase.auth.updateUser({ email })を使用してメールアドレスを変更するとデフォルトの設定では新しいメールアドレスと現在のメールアドレス両方に確認リンクが記載されたメールが飛ぶようになっています。

この確認リンクを片方だけクリックした状態の時と、両方ともクリック済みで変更が完了した状態とでページに表示させる内容を分けたかったので調べてみました。

auth.usersテーブルにはemail_change_confirm_statusというドンピシャなカラムがあるのですが、なぜかsupabase.auth.getUser()supabase.auth.getSession()でもその値の取得ができなかったため他の方法で判別することにしました。(本番環境では取得できるのかもしれないが未確認)

結論

supabase.auth.getUser()で取得できるuser.emailuser.identities[0].identity_data.emailを比較する。

まずawait supabase.auth.updateUser({ email })を実行するとuser.identities[0].identity_data.emailが新しいメールアドレスに変わります。 どちらか一方の確認リンクをクリックした状態では上記の値は変わりません。 両方の確認リンクをクリックして初めてuser.emailも新しいメールアドレスに変わります。

そのためawait supabase.auth.verifyOtp({ type, token_hash })Email Auth with PKCE flow for SSRを参照)をした後のリダイレクト先ページで上記2つの値を比較して異なれば、どちらか片方の確認リンクをクリックした状態、同じであれば両方クリックした状態と判定することができます。

まとめ

実際の挙動から判別しているためこの方法が正しいのかどうかは疑わしい…。