feat: secure account sharing via public-key encryption (#107)
Replace the insecure plaintext QR export/import flow with an end-to-end-encrypted account-transfer mechanism: - Receiver generates an ephemeral X25519 key pair (20-minute lifetime, stored in the new share_keys DB table at schema v31) and displays it as a QR code (sharedinbox.de:pubkey:v1:…). - Sender scans the public-key QR, selects accounts (or auto-selects when only one exists), encrypts them with ECIES (X25519-ECDH + HKDF-SHA256 + AES-256-GCM) and displays an encrypted QR (sharedinbox.de:encrypted-accounts:v1:…). - Receiver scans the encrypted QR, decrypts, verifies the 20-minute expiry and MAC authentication tag, then imports the accounts. New screens: AccountReceiveScreen (/accounts/receive) and AccountSendScreen (/accounts/send), accessible from the account-list drawer and per-account popup menu respectively. Remove the old insecure AccountExportScreen and AccountImportScreen. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
c21d198a25
commit
04e65d2fba
@@ -14,7 +14,7 @@ void main() {
|
||||
group('Migration', () {
|
||||
test('schemaVersion matches expected value', () async {
|
||||
final db = AppDatabase(NativeDatabase.memory());
|
||||
expect(db.schemaVersion, 30);
|
||||
expect(db.schemaVersion, 31);
|
||||
await db.close();
|
||||
});
|
||||
|
||||
@@ -382,7 +382,7 @@ void main() {
|
||||
if (dbFile.existsSync()) dbFile.deleteSync();
|
||||
});
|
||||
|
||||
test('fresh install creates all tables at schemaVersion 30', () async {
|
||||
test('fresh install creates all tables at schemaVersion 31', () async {
|
||||
final db = AppDatabase(NativeDatabase.memory());
|
||||
await db.select(db.accounts).get();
|
||||
|
||||
@@ -407,6 +407,7 @@ void main() {
|
||||
'undo_actions',
|
||||
'search_history_entries',
|
||||
'local_sieve_scripts', // v29
|
||||
'share_keys', // v31
|
||||
]),
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user