mirror of
https://github.com/nostr-protocol/nips.git
synced 2024-12-24 17:35:50 -05:00
Adds Sharing with Read-only and Write Permissions
This commit is contained in:
parent
22543a6a94
commit
973cd23540
109
73.md
109
73.md
|
@ -15,23 +15,19 @@ Event kind `35337` describes a workbook with `data` tags that contain the value
|
||||||
"kind": 35337,
|
"kind": 35337,
|
||||||
"tags": [
|
"tags": [
|
||||||
["d", "<unique identifier>"],
|
["d", "<unique identifier>"],
|
||||||
["title", "Name of this spreadsheet"] // public title
|
["title", "Name of this spreadsheet"], // public title
|
||||||
["data", "<sheet name>", "<column letter>", "<row number>", "<value>"]
|
["data", "<sheet name>", "<column letter>", "<row number>", "<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": nip44Encrypt([
|
"content": "",
|
||||||
["title", "Name of this spreadsheet"] // private title
|
|
||||||
["data", "<sheet name>", "<column letter>", "<row number>", "<value>"] // private data
|
|
||||||
// ... other tags
|
|
||||||
]),
|
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Sheets MUST be rendered in the order of their tags.
|
Sheets MUST be rendered in the order of their tags.
|
||||||
|
|
||||||
## Example
|
As an example:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
@ -49,3 +45,96 @@ Sheets MUST be rendered in the order of their tags.
|
||||||
"sig": "880eb3d67fc66ca2d4e7819ae9b9ca577df35950fb5d11d24f95f350cfeab0b4532646c52113d5bb629cf9a2e4d8ef646ff434b59f1c894c8f719f65d59ed8f0",
|
"sig": "880eb3d67fc66ca2d4e7819ae9b9ca577df35950fb5d11d24f95f350cfeab0b4532646c52113d5bb629cf9a2e4d8ef646ff434b59f1c894c8f719f65d59ed8f0",
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Styling
|
||||||
|
|
||||||
|
TBD
|
||||||
|
|
||||||
|
## Private SpreadSheets
|
||||||
|
|
||||||
|
A private spreadsheet has all tags in a JSON-stringified and NIP-44-encrypted to the user's own pubkey `.content`
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"kind": 35337,
|
||||||
|
"tags": [
|
||||||
|
["d", "<unique identifier>"]
|
||||||
|
],
|
||||||
|
"content": nip44Encrypt([
|
||||||
|
["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>", "<style>"],
|
||||||
|
["style", "<TBD>"], // Need to specify all options here.
|
||||||
|
// ... other tags
|
||||||
|
], privateKey, pubkey),
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sharing Encrypted Spreadsheets with Viewer-only permission.
|
||||||
|
|
||||||
|
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 `.content` is then encrypted by a conversation key between the new private and the public key.
|
||||||
|
|
||||||
|
```js
|
||||||
|
val keyPair = nostr.generateKeyPair()
|
||||||
|
|
||||||
|
{
|
||||||
|
"kind": 35337,
|
||||||
|
"tags": [
|
||||||
|
["d", "<unique identifier>"]
|
||||||
|
["p", "<pubkey 1>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, "<pubkey 1>") ]
|
||||||
|
["p", "<pubkey 2>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, "<pubkey 2>") ]
|
||||||
|
["p", "<pubkey 3>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, "<pubkey 3>") ]
|
||||||
|
],
|
||||||
|
"content": nip44Encrypt([
|
||||||
|
["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>", "<style>"],
|
||||||
|
["style", "<TBD>"], // Need to specify all options here.
|
||||||
|
// ... other tags
|
||||||
|
], keyPair.privateKey, keyPair.publicKey),
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|
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 Spreadsheets with Editor permission.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
```js
|
||||||
|
val keyPair = nostr.generateKeyPair()
|
||||||
|
|
||||||
|
{
|
||||||
|
"pubkey": keyPair.publicKey
|
||||||
|
"kind": 35337,
|
||||||
|
"tags": [
|
||||||
|
["d", "<unique identifier>"]
|
||||||
|
["p", "<pubkey 1>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, "<pubkey 1>") ]
|
||||||
|
["p", "<pubkey 2>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, "<pubkey 2>") ]
|
||||||
|
["p", "<pubkey 3>", "<relay url>", nip44Encrypt(keyPair.privateKeyHex, "<pubkey 3>") ]
|
||||||
|
],
|
||||||
|
"content": nip44Encrypt([
|
||||||
|
["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>", "<style>"],
|
||||||
|
["style", "<TBD>"], // Need to specify all options here.
|
||||||
|
// ... other tags
|
||||||
|
], keyPair.privateKey, keyPair.publicKey),
|
||||||
|
"sig": signWith(id, keyPair.privateKey)
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To edit, receivers SHOULD find the ciphertext for their key, decrypt that to get the shared private key and use the shared private key to encrypt the `.content` and sign the event.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user