intent gatekeeper initial

This commit is contained in:
Fabian Freund
2026-04-19 02:23:04 +02:00
parent 5e6cc7a0f1
commit 57c3dcca86
27 changed files with 1413 additions and 12 deletions
@@ -27,12 +27,33 @@ import 'package:simple_intent_receiver/simple_intent_receiver.dart';
import 'package:uri_to_file/uri_to_file.dart' as uri_to_file;
import 'package:weblibre/core/logger.dart';
import 'package:weblibre/data/models/received_intent_parameter.dart';
import 'package:weblibre/features/intent_gatekeeper/domain/services/intent_gatekeeper.dart';
part 'sharing_intent.g.dart';
final _sharingIntentTransformer =
StreamTransformer<Intent, ReceivedIntentParameter>
_buildSharingIntentTransformer(IntentGatekeeper gatekeeper) =>
StreamTransformer<Intent, ReceivedIntentParameter>.fromHandlers(
handleData: (intent, sink) async {
// PWA shortcut intents carry our own signed context id — always allow.
final pwaContextId =
intent.action == 'android.intent.action.VIEW'
? intent.extra['pwa_context_id'] as String?
: null;
if (pwaContextId == null) {
final allowed = await gatekeeper.shouldAllow(
fromPackageName: intent.fromPackageName,
url: intent.data,
);
if (!allowed) {
logger.i(
'Blocked intent from ${intent.fromPackageName ?? 'unknown app'}',
);
return;
}
}
final data = switch (intent.action) {
'android.intent.action.PROCESS_TEXT' =>
intent.extra['android.intent.extra.PROCESS_TEXT'] as String?,
@@ -46,10 +67,7 @@ final _sharingIntentTransformer =
};
// Extract container context from shortcut intents
final contextId =
intent.action == 'android.intent.action.VIEW'
? intent.extra['pwa_context_id'] as String?
: null;
final contextId = pwaContextId;
if (data != null) {
if (uri_to_file.isUriSupported(data)) {
@@ -101,6 +119,7 @@ final _sharingIntentTransformer =
@Riverpod(keepAlive: true)
Raw<Stream<ReceivedIntentParameter>> sharingIntentStream(Ref ref) {
final receiver = IntentReceiver.setUp();
final gatekeeper = ref.watch(intentGatekeeperProvider.notifier);
return receiver.events.transform(_sharingIntentTransformer);
return receiver.events.transform(_buildSharingIntentTransformer(gatekeeper));
}
@@ -56,4 +56,4 @@ final class SharingIntentStreamProvider
}
String _$sharingIntentStreamHash() =>
r'486f994fc0e01a2cffdb19d93f0a332f96a9850c';
r'21b189c5df56f81ed5ab88115c11ddce1189cfb7';