feat(chat): disallow links in messages
Local-first chat between people whose web of trust is still forming is a natural phishing/scam vector, so messages may not contain URLs. A conservative `containsUrl` rule (explicit scheme, www., or a common-TLD domain — but not "3.5kg" or "12.30") gates it: the composer warns and keeps the text for editing, and MessagesCubit.send drops any URL as a backstop. Incoming text was already non-tappable (plain selectable text).
This commit is contained in:
parent
6a6a81e8a2
commit
1ab243f29e
14 changed files with 107 additions and 34 deletions
31
apps/app_seeds/test/domain/message_rules_test.dart
Normal file
31
apps/app_seeds/test/domain/message_rules_test.dart
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:tane/domain/message_rules.dart';
|
||||
|
||||
void main() {
|
||||
group('containsUrl', () {
|
||||
test('flags explicit schemes and www', () {
|
||||
expect(containsUrl('look https://evil.example/login'), isTrue);
|
||||
expect(containsUrl('http://foo'), isTrue);
|
||||
expect(containsUrl('go to www.example.org now'), isTrue);
|
||||
});
|
||||
|
||||
test('flags bare domains with a common TLD', () {
|
||||
expect(containsUrl('see tomate.com'), isTrue);
|
||||
expect(containsUrl('my-shop.store has it'), isTrue);
|
||||
expect(containsUrl('grab it at bit.ly'), isFalse); // ly not in the list
|
||||
});
|
||||
|
||||
test('leaves ordinary seed talk alone', () {
|
||||
expect(containsUrl('tengo 3.5kg de tomate rosa'), isFalse);
|
||||
expect(containsUrl('variedad F1 vs polinización abierta'), isFalse);
|
||||
expect(containsUrl('nos vemos a las 12.30'), isFalse);
|
||||
expect(containsUrl('semillas de calabaza, ¿cambiamos?'), isFalse);
|
||||
expect(containsUrl(''), isFalse);
|
||||
});
|
||||
|
||||
test('is case-insensitive', () {
|
||||
expect(containsUrl('HTTPS://EXAMPLE.COM'), isTrue);
|
||||
expect(containsUrl('Example.COM'), isTrue);
|
||||
});
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue