通知
Libre WebUI はユーザーごとの永続的な通知受信トレイを保持します。メンション、ダイレクトメッセージ、共有、オートメーションの失敗、カレンダーのリマインダーなど、チームでの出来事を、該当ページを閉じている人にも届けます。
受信トレイ
通知は、まずデータベース行として保存されます。タイトルと本文は保存時に暗号化され、ユーザー 1 人あたり 500 件を上限として古いものから削除されます。任意のソースキーによる重複排除もできるため、同じ通知を繰り返し発行してもベルを埋め尽くさず、1 件にまとめられます。RESTful インターフェースでは、一覧表示、未読数の取得、既読化(1 件またはすべて)、削除ができます。
ライブ配信では、ユーザーごとの永続イベントストリーム notify:<userId> を GET /api/notifications/events(SSE)経由で利用します。ストリームの ID は認証済みセッションから取得し、クライアント入力からは決して取得しません。SQL 受信トレイが正本であり、イベントを受信できなかった場合は、ストリームを再生するのではなく一覧を読み取って回復します。
通知が生成される場面
| 種類 | 生成条件 |
|---|---|
channel-dm | 誰かがあなたにダイレクトメッセージを送信したとき |
channel-mention | チャンネルで誰かがあなたを @mentions したとき、またはあなたのメッセージへ返信したとき |
channel-invite | あなたがチャンネルに追加されたとき |
share | 誰かがあなたとリソースを共有したとき |
automation-failed | あなたのオートメーションの 1 つが失敗したとき(通知を無効にしている場合を除く) |
calendar-reminder | リマインダー間隔を指定したイベントが通知時刻に達したとき |
work-run-finished | 雇用した Work エージェントの 1 つが実行を完了したとき |
work-run-attention | 雇用したエージェントが入力待ちで停止したとき、またはエラーになったとき |
work-takeover | Work エージェントから画面の引き継ぎを求められたとき |
work-approval | Work の実行が、副作用を伴うアクションの承認を待っているとき |
system | インスタンス全体のお知らせ |
通知は、影響を受けるユーザーだけに必ず発行されます。チャンネルのメンバーでないユーザー名をメンションしても、通知は生成されません。
送信 Webhook
管理者は、チームイベントを受信する Webhook の送信先を登録できます。
- 外向き通信の保護。 送信先にはツールサーバーと同じ宛先ポリシーが適用されます。URL は完全一致で、リダイレクトは許可されません。管理者が
TOOLS_PRIVATE_NETWORK_ALLOWLISTでホストを明示的に許可しない限り、プライベートアドレスやリンクローカルアドレスも禁止されます。配信のたびにホスト名を再解決し、再確認します。 - 署名。 シークレットが設定されている場合、すべての配信に
X-Libre-Signature: sha256=<hmac>が付きます。これは実際の本文全体から計算されます。 - 秘匿化。 エンベロープに含まれるのは、イベント種別、通知種別、タイトル、識別子、タイムスタンプです。通知本文、メッセージ内容、プロンプト、ドキュメントがインスタンスの外へ出ることはありません。
- 永続性。 配信は、回数に上限のある再試行付きの永続ジョブとして実行されます。受信側の 5xx 応答は再試行し、4xx 応答は受信側による最終判断として扱い終了します。
- スコープ。 各送信先は、特定の通知種別(または
*)を購読します。
ブラウザプッシュ
設定 → 通知で、このブラウザを Web Push に登録できます。タブを閉じていても、メンション、共有、リマインダー、完了した作業がデバイスへ届きます。実装には標準仕様だけを使い、自己完結しています。
- VAPID(RFC 8292)。 サーバーは ES256 鍵ペアで各配信に署名します。鍵ペアは一度だけ生成して暗号化保存するか、
VAPID_PUBLIC_KEY/VAPID_PRIVATE_KEYで固定します(VAPID_SUBJECTは連絡先クレームを設定します)。ブラウザベンダーのプッシュエンドポイントを除き、第三者のプッシュライブラリやサービスアカウントは使用しません。 - 暗号化ペイロード(RFC 8291)。 各メッセージはインスタンスを出る前に、デバイス固有の鍵を使った aes128gcm で暗号化されます。プッシュサービスは読み取れない暗号文だけを中継します。
- デバイス単位、セッションへの紐付け。 サブスクリプションは、それを作成したブラウザと、そのブラウザの認証セッションに属します。セッションからサインアウトすると(「他のセッションからサインアウト」した場合も)、プッシュ登録も削除されます。エンドポイントは鍵付き検索トークンとともに暗号化して保存され、公開 HTTPS 宛先でなければなりません。Webhook と同じ外向き通信の安全対策が適用されます。
- 永続性。 プッシュ配信は、回数に上限のある再試行付きの永続ジョブとして実行されます。プッシュサービスからサブスクリプションが消失したとの応答(404/410)があれば、その登録を削除します。
- ペイロードには、通知タイトル、任意の本文、種類、リンク先が含まれます。秘匿化の方針は受信トレイと同じです。
プッシュには、本番アプリ(サービスワーカーが登録されるのは本番だけ)と安全なオリジンが必要です。オフラインシェルとインストール機能も同じサービスワーカーが提供します。アプリマニフェストにより Libre WebUI をインストール可能にし、オフライン時のナビゲーションはキャッシュ済みシェルへフォールバックし、ハッシュ付きビルドアセットは不変としてキャッシュします。API トラフィックは一切キャッシュしません。
境界
- 種類別のユーザー設定はまだ実装されていません。オートメーションは自身の通知設定に従い、チャンネルを退出するとそのチャンネルからの通知は停止します。