feat(base,app,keys): keys of shared spaces, sealed to each member
Step 3 of ADR 0044 (D3, D18, D19). A shared space's data keys are sealed on a device to each member's public keys; the instance keeps what devices sealed and never opens it. - halkyon_keys: the safety code of two accounts' public keys (`safetyCode`), 60 digits, the same on both sides. - halkyon_base: the register hands out accounts' public keys (`public-keys-of`, local and remote); the table `shared_space_key` and the endpoint `sharedSpaceKeys` (memberKeys, keysNeeded, seal, mine). Only the Owner and Editors seal, the first key sealed to a member stays, and a member's keys go with their membership. Every host's migration creates the table. - halkyon_app: `ContentCipher` seals a key to another account and opens one sealed by another; `SharedKeys` shares a space's key with its members, seals keys to newcomers and opens the person's own, holding each member to the public keys `KeyPins` pinned on first sight (`key_pins.json` in the person's folder), a change refused until trusted anew. Learn takes them into its `Privacy` in step 4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
d08d8ad545
commit
b72cea1fe0
5 changed files with 105813 additions and 5 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,134 @@
|
|||
{
|
||||
"__className__": "serverpod.DatabaseMigration",
|
||||
"actions": [
|
||||
{
|
||||
"__className__": "serverpod.DatabaseMigrationAction",
|
||||
"type": "createTable",
|
||||
"createTable": {
|
||||
"__className__": "serverpod.TableDefinition",
|
||||
"name": "shared_space_key",
|
||||
"dartName": "SharedSpaceKey",
|
||||
"module": "halkyon_base",
|
||||
"schema": "public",
|
||||
"columns": [
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "id",
|
||||
"fieldName": "id",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"columnDefault": "random_v7",
|
||||
"dartType": "UuidValue?"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "sharedSpaceId",
|
||||
"fieldName": "sharedSpaceId",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"dartType": "UuidValue"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "keyId",
|
||||
"fieldName": "keyId",
|
||||
"columnType": 0,
|
||||
"isNullable": false,
|
||||
"dartType": "String"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "recipientId",
|
||||
"fieldName": "recipientId",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"dartType": "UuidValue"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "sealedKey",
|
||||
"fieldName": "sealedKey",
|
||||
"columnType": 5,
|
||||
"isNullable": false,
|
||||
"dartType": "dart:typed_data:ByteData"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "sealedBy",
|
||||
"fieldName": "sealedBy",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"dartType": "UuidValue"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "createdAt",
|
||||
"fieldName": "createdAt",
|
||||
"columnType": 4,
|
||||
"isNullable": false,
|
||||
"dartType": "DateTime"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"__className__": "serverpod.ForeignKeyDefinition",
|
||||
"constraintName": "shared_space_key_fk_0",
|
||||
"columns": [
|
||||
"sharedSpaceId"
|
||||
],
|
||||
"referenceTable": "shared_space",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4
|
||||
}
|
||||
],
|
||||
"indexes": [
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "shared_space_key_unique_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "sharedSpaceId"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "keyId"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "recipientId"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": true,
|
||||
"isPrimary": false
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "shared_space_key_recipient_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "recipientId"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
}
|
||||
],
|
||||
"managed": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"warnings": [],
|
||||
"migrationApiVersion": 1
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@ part '20261026140329810-assistant-budgets/migration.dart';
|
|||
part '20261110225336783-file-store-in-halkyon-base/migration.dart';
|
||||
part '20261110225358224-file-store-in-halkyon-base/migration.dart';
|
||||
part '20261111091720823-shared-spaces/migration.dart';
|
||||
part '20261111100124819-shared-space-keys/migration.dart';
|
||||
|
||||
/// Migration registry for the client-side database.
|
||||
class MigrationRegistry {
|
||||
|
|
@ -76,6 +77,7 @@ class MigrationRegistry {
|
|||
_Migration20261110225336783_file_store_in_halkyon_base(),
|
||||
_Migration20261110225358224_file_store_in_halkyon_base(),
|
||||
_Migration20261111091720823_shared_spaces(),
|
||||
_Migration20261111100124819_shared_space_keys(),
|
||||
];
|
||||
|
||||
/// List of all client-side database migration versions.
|
||||
|
|
|
|||
Loading…
Reference in a new issue