Refinements to the public but edit-reserved spreadsheets

This commit is contained in:
Vitor Pamplona 2024-05-02 14:18:56 -04:00
parent 751283f3c9
commit 4fbac8d769

39
73.md
View File

@ -20,7 +20,7 @@ Event kind `35337` describes a workbook with `data` tags that contain the value
["data", "<sheet name>", "<column letter>", "<row number>", "<value>", "<style>"], ["data", "<sheet name>", "<column letter>", "<row number>", "<value>", "<style>"],
["style", "<TBD>"], // Need to specify all options here. ["style", "<TBD>"], // Need to specify all options here.
], ],
"content": "", "content": "", // reserved for private content below
// ... // ...
} }
``` ```
@ -50,9 +50,9 @@ As an example:
TBD TBD
## Private SpreadSheets ## Private Spreadsheets
A private spreadsheet has all tags in a JSON-stringified and NIP-44-encrypted to the user's own pubkey `.content` A private spreadsheet has tags in a JSON-stringified and NIP-44-encrypted to the user's own pubkey `.content`
```js ```js
{ {
@ -66,16 +66,16 @@ A private spreadsheet has all tags in a JSON-stringified and NIP-44-encrypted to
["data", "<sheet name>", "<column letter>", "<row number>", "<value>", "<style>"], ["data", "<sheet name>", "<column letter>", "<row number>", "<value>", "<style>"],
["style", "<TBD>"], // Need to specify all options here. ["style", "<TBD>"], // Need to specify all options here.
// ... other tags // ... other tags
], privateKey, pubkey), ], author.privateKey, author.pubkey),
// ... // ...
} }
``` ```
## Sharing Encrypted Spreadsheets with Viewer-only permission. ## Sharing Encrypted Spreadsheets with View-only permission to a Group
Ready-only sharing is achieved by adding a `p` tag to each receiver with a shared secret to decrypt the `.content`. Ready-only sharing is achieved by adding a `p` tag to each receiver with a shared secret to decrypt the `.content`.
The shared secret is a Nostr Private Key in hex, NIP-44-encrypted to each `p` tag and placed as a 4th value in each tag. The shared secret is a new Nostr Private Key in hex, NIP-44-encrypted to each `p` tag and placed as a 4th value in each tag.
The `.content` is then encrypted by a conversation key between the new private and the public key. The `.content` is then encrypted by a conversation key between the new private and the public key.
@ -83,12 +83,13 @@ The `.content` is then encrypted by a conversation key between the new private a
val keyPair = nostr.generateKeyPair() val keyPair = nostr.generateKeyPair()
{ {
"pubkey": author.pubkey
"kind": 35337, "kind": 35337,
"tags": [ "tags": [
["d", "<unique identifier>"] ["d", "<unique identifier>"]
["p", "<pubkey 1>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, "<pubkey 1>") ] ["p", "<pubkey 1>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, author.privateKey, "<pubkey 1>") ]
["p", "<pubkey 2>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, "<pubkey 2>") ] ["p", "<pubkey 2>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, author.privateKey, "<pubkey 2>") ]
["p", "<pubkey 3>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, "<pubkey 3>") ] ["p", "<pubkey 3>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, author.privateKey, "<pubkey 3>") ]
], ],
"content": nip44Encrypt([ "content": nip44Encrypt([
["title", "Name of this spreadsheet"], // private title ["title", "Name of this spreadsheet"], // private title
@ -97,15 +98,16 @@ val keyPair = nostr.generateKeyPair()
["style", "<TBD>"], // Need to specify all options here. ["style", "<TBD>"], // Need to specify all options here.
// ... other tags // ... other tags
], keyPair.privateKey, keyPair.publicKey), ], keyPair.privateKey, keyPair.publicKey),
"sig": signWith(author.privateKey)
// ... // ...
} }
``` ```
To decrypt, receivers SHOULD find the ciphertext for their key, decrypt that to get the shared private key and use the shared private key to decrypt the `.content`. To decrypt, receivers SHOULD find the `p`-tag ciphertext for their key, decrypt that to get the shared private key and use the shared private key to decrypt the `.content`.
Clients SHOULD include the author as a `p` tag to save the secret that will allow the author to decrypt and modify the event further. Clients SHOULD include the author as a `p` tag to save the secret that will allow the author to decrypt and modify the event further.
## Sharing Encrypted or Public Spreadsheets with Edit permission. ## Sharing Encrypted or Public Spreadsheets with Edit permission to a Group
This method allows anyone listed as the `p` tag to edit the Spreadsheet. It follows a similar process to read-only spreadsheets, but instead of signing the event with the author's main key, the event is signed by the shared secret as well. This method allows anyone listed as the `p` tag to edit the Spreadsheet. It follows a similar process to read-only spreadsheets, but instead of signing the event with the author's main key, the event is signed by the shared secret as well.
@ -117,18 +119,23 @@ val keyPair = nostr.generateKeyPair()
"kind": 35337, "kind": 35337,
"tags": [ "tags": [
["d", "<unique identifier>"] ["d", "<unique identifier>"]
["p", "<pubkey 1>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, "<pubkey 1>") ] ["p", "<pubkey 1>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, keyPair.privateKey, "<pubkey 1>") ]
["p", "<pubkey 2>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, "<pubkey 2>") ] ["p", "<pubkey 2>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, keyPair.privateKey, "<pubkey 2>") ]
["p", "<pubkey 3>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, "<pubkey 3>") ] ["p", "<pubkey 3>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, keyPair.privateKey, "<pubkey 3>") ]
["title", "Name of this spreadsheet"], // public title
["data", "<sheet name>", "<column letter>", "<row number>", "<value>"], // public data
["data", "<sheet name>", "<column letter>", "<row number>", "<value>", "<style>"],
["style", "<TBD>"], // public styles
], ],
"content": nip44Encrypt([ "content": nip44Encrypt([
["title", "Name of this spreadsheet"], // private title ["title", "Name of this spreadsheet"], // private title
["data", "<sheet name>", "<column letter>", "<row number>", "<value>"], // private data ["data", "<sheet name>", "<column letter>", "<row number>", "<value>"], // private data
["data", "<sheet name>", "<column letter>", "<row number>", "<value>", "<style>"], ["data", "<sheet name>", "<column letter>", "<row number>", "<value>", "<style>"],
["style", "<TBD>"], // Need to specify all options here. ["style", "<TBD>"], // private styles
// ... other tags // ... other tags
], keyPair.privateKey, keyPair.publicKey), ], keyPair.privateKey, keyPair.publicKey),
"sig": signWith(id, keyPair.privateKey) "sig": signWith(keyPair.privateKey)
// ... // ...
} }
``` ```