feat(app): content sealed with data keys, and an anonymous person's device keys (ADR 0019)
`ContentCipher` makes a person's data keys, sealed to their account and signed by it, opens them, and seals and opens a row's content with them for the row it is stored in (`SodiumContentCipher`, on the isolate it is used on, as rows are read and written one by one; `FakeContentCipher` for tests). A sealed payload holds the signature, then the ciphertext. `AccountCrypto.newDeviceKeys` makes the key pairs an anonymous person's device encrypts their private studysets with (ADR 0017, point 9, not built before); setting a password keeps them as the account's (`keepingKeys` with a new phrase), so nothing they made private is lost. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
a1c5ac3f86
commit
905bb9abf2
1 changed files with 476 additions and 9 deletions
|
|
@ -325,6 +325,38 @@ void main() {
|
|||
expect(addresses.addresses['anonymous-1'], 'dana@example.org');
|
||||
});
|
||||
|
||||
test("an anonymous person's device keys become their account's as they "
|
||||
'set a password, so their private studysets stay readable', () async {
|
||||
await auth.signInAnonymously();
|
||||
final device = await crypto.newDeviceKeys();
|
||||
await keys.keep('anonymous-1', device);
|
||||
final request = await passwords.sendCode(
|
||||
'dana@example.org',
|
||||
language: 'en',
|
||||
purpose: MailCodePurpose.signUp,
|
||||
);
|
||||
|
||||
final material = await passwords.makePassword('her password');
|
||||
await passwords.setPassword(
|
||||
material,
|
||||
address: 'dana@example.org',
|
||||
request: request,
|
||||
code: gateway.codeFor('dana@example.org'),
|
||||
);
|
||||
|
||||
expect(material.keys, device);
|
||||
expect(keys.kept['anonymous-1'], device);
|
||||
});
|
||||
|
||||
test('someone signed up anew gets new keys, never the keys kept on the '
|
||||
'device for another', () async {
|
||||
await keys.keep('anonymous-1', crypto.keysNumbered(1));
|
||||
|
||||
final material = await passwords.makePassword('a new password');
|
||||
|
||||
expect(material.keys, isNot(crypto.keysNumbered(1)));
|
||||
});
|
||||
|
||||
test("keeps only the signed-in person's keys: another signing in, or "
|
||||
'signing out, takes the others away', () async {
|
||||
await auth.signInAnonymously();
|
||||
|
|
|
|||
Loading…
Reference in a new issue