2025/06/20

Angularの*ng~ディレクティブについて

従来

 Angularでは状況に応じてHTMLの内容を変更する際に以下のディレクティブを使用します。

  • *ngIf
  • *ngSwitch, *ngSwitchCase, *ngSwitchDefault
  • *ngFor

 これらのディレクティブは以下のタグと組み合わせて使用することもあります。

  • ng-container
  • ng-content
  • ng-template

 使い方を説明した記事はネット上に既にたくさんあるので詳細は説明しませんが、以下のような感じになります。

<div *nfIf="isProcessing; then processingMess; else doneMess"></div>

<ng-template #processingMess>
    <span>処理中...</span>
</ng-template>

<ng-template #doneMess>
    <span>完了!</span>
</ng-template>
<div [ngSwitch]="processState">
    <span *ngSwitchCase="PREPARING">準備中.</span>
    <span *ngSwitchCase="PROCESSING">処理中...</span>
    <span *ngSwitchCase="DONE">完了!</span>
    <span *ngSwitchDefault> (?o?) </span>
</div>
<table>
    <tr *ngFor="let item of itemList">
        <td>{{item}}</td>
    </tr>
</table>

 ngSwitchやngForの例はまだ何とかわかりますが、ngIfのようにng-templateなどとの組み合わせになると直感的でなくて、わかりにくいと大変不評です。


Angular17以降

 Angular17で、以下の新しい構文が追加されました。
  • @if, @else, @else if
  • @switch, @case, @default
  • @for, @empty

 これらは直感的に書けるように改善されています。

<span>
    @if (isProcessing) {
        処理中...
    } @else {
        完了!
    }
</span>
<span>
    @switch (processState) {
        @case ("PREPARING") {準備中.}
        @case ("PROCESSING") {処理中...}
        @case ("DONE") {完了!}
        @default { (?o?) }
    }
</span>
<table>
    @for (item of itemList; track item) {
        <tr>
            <td>{{item}}</td>
        </tr>
    }
    @empty {
        <tr>
            <td>空っぽです</td>
        </tr>
    }
</table>

 @emptyに対応する*ng~ディレクティブはなさそうです。探してみたのですが見つかりません。


 一度使ってしまうと、もう*ng~ディレクティブには戻れません。


2025/06/08

LotteryServアップデート

  LotteryServを更新しました。前回2025/05/06の更新に続いて、今回の更新もセキュリティの強化が中心です。


ワンタイムパスワード認証に対応

 多要素認証の第2要素として、ワンタイムパスワード認証を追加しました。

 多要素認証はログインできなくなった場合への備えとして複数の第2認証を登録することを勧めていますが、前回のアップデートで対応したSMS認証のみでは、複数のスマートフォン/携帯電話が必要になり、現実的とは言い難い状況でした。今回ワンタイムパスワード認証を追加したことで、スマートフォン/携帯電話は1台でも2つの第2認証に対応できるようになります。

 ワンタイムパスワードアプリは、以下の2つで動作することを確認しています。

  • Google Authenticator
  • Microsoft Authenticator


 ただし機種変更時の移行には、あらかじめワンタイムパスワード認証の設定をアカウントに保存するなど準備をしておくか、新旧2台を並べて操作するかが必要なようです。ご注意ください。


第2認証の完全な削除を可能に

 前回のアップデートでは、第2認証を複数登録した場合は1つずつ削除が可能でしたが、最後の1つの第2認証は削除不可能という制限がありました。今回のアップデートでその制限はなくなりました。

 すべての第2認証を削除すると、ログイン・再認証は第2認証なしとなります。もちろんこの場合は多要素認証の設定がないので、アカウントは脆弱な状態となります。

 多要素認証の設定がないユーザでは募集の開始ができない制限は、前回2025/05/06の更新からのものです。この制限はクレジットカード決済の悪用による被害を防ぐためのものです。


UIのモダナイズ

 前記ワンタイムパスワード認証の追加に伴い、主催者ログイン画面など一部の画面をモダンなデザイン・実装に変更しました。

 また他の画面でもごく一部に画面遷移やデザインを変更した個所がありますが、使い方には変化はありません。


メールでログインでもアイコンを利用可能に

 Eメールアドレス/パスワードでログインするアカウントの場合、従来はアイコンが固定でした。

 インタネット上に公開されているアイコンがある場合、そのアイコンのURIを指定していただくことで、LotteryServ上でもそのアイコンを表示するようになりました。

 ただ、現在このアイコンを表示するのは、ユーザメニューの最初の項目のみです。


その他軽微な不具合の修正

 詳細の説明は割愛いたしますが、軽微な不具合を複数修正しています。

2025/06/06

Firebaseコンソールの不具合

 Firebase Authenticationで多要素認証を実装しようとしていて発見した、Firebaseコンソールの不具合です。


準備

まずはテスト用の電話番号を登録します。SMSを受信できるスマホや携帯電話が2台以上あれば、テスト用の電話番号は不要かもしれません。

テスト用電話番号の登録手順は以下のとおり。この手順を説明した記事は少なそうだったので、念のため記載します。

  1. FirebaseコンソールでAuthenticationを選択。
  2. 画面上部のタブで「ログイン方法」を選択。

  3. 「SMS多要素認証」の「変更」を押下。

  4. ダイアログの「有効にする」をチェックして
  5. 「テスト用の電話番号」を押下するとダイアログが伸びてテスト用の電話番号の設定が現れます。
  6. 適当な電話番号(日本なので"+81aabbbbcccc")と確認コード(10進数6桁)を入力して、
  7. 「保存」を押下。


発生手順

手順の際現にはSMS認証による多要素認証をFirebase Authenticationで実装したアプリが必要です。ない場合はFirebaseのquickstart-jsでも再現できます。

以下にquickstart-jsによる再現手順を示します。

  1. SMS multi-factor authenticationを選択。

  2. 登録してある任意のアカウントのEメールアドレスとパスワードを入力して「SIGN IN」を押してログイン。
  3. 「ENROLL」を押下して第2認証のSMS認証の登録を開始。
  4. SMS認証に追加する電話番号を入力。準備で設定したテスト用の番号で十分です。

  5. reCAPTCHAをチェックしたら「SEND CODE」を押下。ここで"Firebase: Error (auth/requires-recent-login)."が発生したらいったんSIGN OUTし、手順2からログインしなおし。
  6. 届いたSMSに記載されている認証コードと、任意の表示名を入力して「VERIFY CODE」を押下。ここでは表示名は"test SMS 1"としています。
  7. SMS認証の追加が完了し、結果が表示されます。
  8. FirebaseコンソールのAuthenticationで「ユーザー」タブを選択し、SMS認証を追加したユーザの3点リーダを押下してオプションメニューを表示。
  9. オプションメニューから「多要素認証を構成」を選択。
  10. ダイアログの「保存」押下。特に編集しなくても現象は発生します。

  11. アプリquickstart-jsに戻ります。手順10でユーザアカウントを編集しているので、ログアウトしているはずです。ログアウトしていなかったら「SIGN OUT」を押下してログアウトします。
  12. もう一度ログインします。今度は手順3~7で追加した第2認証が必要になっていますので、これも認証します。

現象

アプリquickstart-jsでログインしてみると、第2認証のSMS認証の表示名が「N/A」に変わっています。


複数の電話番号を使えば1人のユーザに対して複数のSMS認証を追加できますが、すべてのSMS認証の表示名が「N/A」に変わってしまいます。

第2認証にワンタイムパスワードを使用している場合、ワンタイムパスワードだけ影響をうけません。SMS認証のみで発生します。


最後に

Firebaseのライブラリでいうと、MultiFactorInfo.displayNameがnullになっているようです。表示名を設定する手段はMultiFactorUser.enroll()しか見つからなかってので、消えてしまった表示名を復活させるには、SMS認証をいったん消して再登録するしかないようです。


一応Firebaseのサポートには報告し、「再現できたから開発チームに報告しておく」と回答をいただきました。そのうち修正されるでしょうが影響を受けるのは開発者のみなので、優先順位は低く対応が遅い可能性があります。Firebase Authenticationで多要素認証を実装・デバッグしていると混乱しかねない現象ですので、ご注意ください。

ちなみにFirebaseのサポートとのやり取りには3週間以上かかっています。