Home / GitHub Page

Sharing notes or notebooks

I’m thinking more of a Joplin-style Viewer App, not necessarily a editing App.

Then nextcloud can be the sharing platform for Joplin.

Yes the way I see it it would almost be a separate project developed by someone else. Maybe for someone who already knows how to develop Nextcloud apps it would be easier.

Hi! I registered just to add to this thread :slight_smile:

I wonder whether this discussion has got a bit too focussed on sharing the actual note files themselves, rather than the concept of sharing a note with someone else? Fundementally, the feature that’s being asked for (I think) is “Can I share one or more notes with someone else”. In my mind, that’s different to “Can I share one or more notes with someone else that also happens to use the same storage backend as me”.

Personally, I’d like to be able to share a note with any Joplin user, not just ones that share my storage backend.

I wonder whether the answer is some kind of app-to-app synchronisation, which updates each person’s clone of the note as changes are made - rather than relying on the storage backend to do that for you (which it probably won’t do optimally, and you’ll end up with conflicts). I know that might require some kind of rendezvous point, which is potentially infrastructure that has to be kept operating by someone - which isn’t neccecarily ideal (cost, admin, etc).

The lack of sharing is really a big factor in why I’m still using other note taking apps - thus my motivation to comment here :slight_smile:

One big issue with sharing notes is E2EE. If a note is encrypted you can’t share it without also sharing the key and password, which obviously shouldn’t be done.

I wonder how other platforms handle this? Or are the platforms that support sharing notes just don’t also support E2EE? (I believe Evernote has note sharing but no E2EE for example).

I’m keen to get this working as I need the feature too but it’s tricky to get right. At this point my thinking is that a note that’s shared simply won’t be encrypted even if E2EE is enabled.

1 Like

Agreed. My initial thoughts would be that, since it’s a per device activity - that the synchronisation is also per device (and therefore the sync data is still encrypted at rest). The inter-user synchronisation could then also be performed over an encrypted channel (for example by implementing the Signal protocol). So in the ideal scenario - your data is encrypted at rest in your own notebook, encrypted during transit between users, and then encrypted at the remote end in the recipient’s notebook.

However, that does assume that both users has E2EE enabled. That could be negated somewhat with a warning when setting up the share if you have E2EE enabled (e.g. “Careful! The person you are sharing this note with may not have encryption enabled, and it may be stored in plain text! - are you sure you wish to proceed?”), so at least the user understands the risks.

And yes, there are a lot of complexities. I’ll come back with some more thoughts if they become a bit more coherent :slight_smile:

may be an idea, a friend of mine, working for a company which encrypt and share files, suggested me to use an external service like pastebin/zerobin which will allow to share and crypt stuff for the people you want.

I think that’s the only feasible solution for this purpose.
Seafile, for instance, has good E2EE support but it doesn’t allow for encrypted libraries to be shared.
As others have suggested there might be ways to solve this problem for shares between Joplin users but I’m sure those solutions blow the scope of the project. Also, I don’t see how share links for non-Joplin users could be done without giving up E2EE for the shares. In this case the option to set a share password should be enough.

Interesting idea - from reading the Zerobin project page (which, incidentally, is unmaintained) they do client side encryption and the server stores the (encrpyted) message against an ID. The client then tacks the symetric AES key onto the share URL which you then send to the other recipient (and doesn’t touch the server). It’s a simple method of creating a secure channel, and relies on a single shared key known only to the client(s).

That would absolutely work in a one directional situation where a creator is sending a note to several clients. But if said clients also want to modify the note, things would get complex fast - how would you maintain sync between multiple clients who may be editing slightly different versions?

You could solve this by descoping collaborative editing (which in fairness I put into scope about a paragraph ago by inferrance). The recipients would get a read only copy at the point of sharing, but that would be it.

I supposed “sharing” by “showing” but not “modifying” notes, in that case it’s dead i think

Yes Joplin supports multiple master keys so I was thinking of having a special Share master key, which you send with the note. It’s complex both at the backend and frontend level (lots of UI to develop for each app) so not sure if it will be done. Sharing notes is complicated so I’m looking for a way to do it one step at a time, and that means the first version is unlikely to support E2EE at all.

There’s also keybase, but I’d refrain from using an external service. The whole idea of Joplin is that you can host it yourself. Using an external service for sharing will break this premise.

i agree
if we want sucha feature in the Joplin World it should be another project

On a whim, I’ve started building something that’s essentially a headless pastebin:
joplin-share-server. (no code yet, fully README driven development…)

The concept is that every Joplin client has AES-128 or 256 encryption ability built into it. Through some means (outside of the scope of what I’m doing here!), a note can be encrypted and sent to this server. When this happens, you get a note ID back from the server, which you can use to build a URL which will be sent to the recipient.

The recipient can then use that note ID to retrieve the (encrypted) contents of the note as initially shared - their client would then place a copy of it (!) into their own notebook. The recipient would be provided with the encryption key somehow (perhaps by using the clever trick that Zerobin did by tacking the key onto the end of the URL with an anchor tag) to decrypt the note.

Of course, the limitation here is that the note is only in sync when it it shared - any updates afterwards are not synchronised. If you updated the note and wanted to share the new contents, you’d need to share it again.

However, it does mean that the key is only required at the point of importing the note - therefore isn’t stored anywhere afterwards, so avoids the problem of plaintext key storage (at least for now).

It’ll run in a Docker container, and could be self hosted.

In fact, after the user has entered the key, couldn’t we store it in the js LocalStorage so that it doesn’t need to be provided every time?

Since it’s client side I guess it can be implemented in such a way that no server can access that particular key, thus keeping it E2EE.

Your repo is 404 by the way.

1 Like

It was private :slight_smile:

So yes - I was thinking you could keep the key in LocalStorage on the device you accepted the share from (I keep changing the langauge I use, I’m not sure what the right words are here!)… but the problem is what happens if you open that note on another device? If you were going to get updates to a note, you’d want any device to be able to get updates - right?

joplin-share-server now has some functionality. You can POST encrypted notes at it, and GET encrypted notes from it.

Currently, that is about it! Whilst there is a version field in the note object, it’s always going to be 1 for the moment until I work out how to send updates.

So, with this “release”, this could be implementeed in the client:

In the sender’s client, it would to encrypt a note with a key (lets say abc123), POST that note to the server - which returns a UUID v4 back to identify it (lets say b0bd7fba-c1b4-46e6-9484-5e047f05df0b).

The sender’s client could then build a URL, like https://share.joplinapp.org/note/b0bd7fba-c1b4-46e6-9484-5e047f05df0b#abc123

The sender then conveys that URL to the recipient somehow.

The recpient’s client could intercept that URL when clicked (definitely possible with React Native, probably with Electron too), then make the HTTP request it to get the encrypted note, then use the key from the anchor tag to decrypt it, then save it in the recipient’s notebook.

One way sending of notes from one person’s notebook to another.

I have an idea for how updates could work, as well. It involves encrypted operation-based CRDT update messages. That’s a bit more ambitious, but if that’s possible you can do real-time collaborative editing potentially.

1 Like

Wait, wait. The E2EE assertions don’t sound right.
Keep in mind that while I’ve read a bunch on this topic and this scheme is based on what I vaguely remember reading, I couldn’t tell you what exactly it was. Feel free to point out any errors, I might be wrong.
I think one of the schemes that would work is:

  1. generate one key as usual, let’s call it General
  2. generate another key per user. This is the one the user has a password for.
  3. encrypt the General key with the User’s.
  4. upload everything to Joplin as usual

Decrypting notes:

  1. Use the user’s password to decrypt his User key
  2. Use that to decrypt the General key
  3. Use the General key to decrypt notes, as usual

Analogously for encryption.

Sharing:

  1. Get the receiving user’s (public) key (Recipient)
  2. Get the unencrypted version of the General key
  3. Encrypt General with Recipient
  4. Upload it

After sync, the receiving user decrypts the General key with his very own private key (from the Recipient’s pair, that is) and is good to go.

So the tld;dr is, you would not directly have the password for the master key, it would instead be encrypted with your personal key. When you need to start sharing, you can encrypt it with the Recipient’s key, never giving your password away, or asking for theirs.

Thoughts? What did I miss?

Ps: if this worked, there would also be a clean migration path from the old model to the new. The current master key would become the user’s key, and a new General (master) would be generated. Yes, this would necessitate re-encrypting the entire database and would incur a substantial (if one-time) performance hit. OTOH, the user would not have to do a thing.

This is assuming that there is a public key. As far as I can tell, they are symetric keys (certainly up until now there would be no need for public / private keys)

1 Like

Come to think of it, maybe all of that will be unnecessary, depending on how the rest of the sharing works.
If I could, for instance, add a notebook that is synced from a different sync target (I’ve seen requests for this, and similar things, around the forum), then that target’s master password could be shared between parties without exposing the rest of my (unshared) notes.

As far as I’m concenred, that would be enough and would require no changes to the encryption scheme.