feat(client): FCM web push registration

web/index.html loads the Firebase compat SDK and defines
window.kcGetPushToken() — inits Firebase from window.KC_FIREBASE, asks for
notification permission, registers the service worker and returns an FCM
token (or null if not configured / denied). web/firebase-messaging-sw.js
shows background notifications.

browser_web.dart exposes getPushToken() over that JS function (stub returns
null off-web). After every successful login AppState fires
_registerForPush() -> POST /api/push/register, best-effort.

Config placeholders carry the known values (projectId konfi-castle-app,
messagingSenderId 307226979593); apiKey / appId / vapidKey still say
REPLACE_ME, so push stays inert until they're filled in — the app runs
either way. flutter analyze/test/build web green.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-10 11:45:01 +02:00
co-authored by Claude Sonnet 5
parent cc663c7e17
commit 530be36458
5 changed files with 86 additions and 0 deletions
+14
View File
@@ -3,6 +3,20 @@ import 'dart:js_interop';
import 'package:web/web.dart' as web;
/// Provided by the inline Firebase bootstrap in web/index.html. Returns an FCM
/// registration token, or null if push isn't configured / permission denied.
@JS('kcGetPushToken')
external JSPromise<JSString?> _kcGetPushToken();
Future<String?> getPushToken() async {
try {
final result = await _kcGetPushToken().toDart;
return result?.toDart;
} catch (_) {
return null;
}
}
/// Per-tab storage for the PKCE verifier + CSRF state (cleared when the tab
/// closes), and the little bit of `window` access the OIDC redirect needs.