Sharing Private Data

How to share private data with the Webnative SDK

You can share a private file or directory with another Fission user:

Here you see a photo being shared from Fission Drive and being accepted by another user in the auth lobby.

Exchange keys

Private shared data uses public keys, which we call exchange keys, that live in a user's public file system under .well-known/exchange/. Exchange keys are unique per domain because webnative generates a key-pair per domain, so we need to add an exchange key to each domain that will accept shares. We can add an exchange key to a file system using:

// Given a file system instance `fs` exists and the program has been initialized
if (program.fileSystem.hasPublicExchangeKey(fs) === false) {
  program.fileSystem.addPublicExchangeKey(fs)
}

The auth lobby automatically does this when we create our account, link a device, or authorise an application.

Creating a share

When the receiver of the share has their exchange key(s) set up, we're ready to create a share:

const shareDetails = fs.sharePrivate(
  [ webnative.path.file() ],
  { shareWith: "username" } // alternative: list of usernames, or sharing/exchange DID(s)
)

That will do an fs.publish() and consequently a data root update, so you'll want to wait until those are complete before accepting a share.

Resolving the share

The shareDetails contain a shareId used to accept or load a share.

fs.acceptShare({
  shareId: shareDetails.shareId,
  sharedBy: shareDetails.sharedBy.username
})

By accepting a share, you create a symbolic link (aka. soft link) to the shared data in the /private/Shared with me/SENDER_USERNAME/ directory. In other words, accepting a share is fs.loadShare() plus copying the soft link from the share:

const share = await fs.loadShare({ shareId, sharedBy })

// Add soft links to the directory
await fs.write(
  webnative.path.directory(
    webnative.path.RootBranch.Private,
    "Shared with me",
    sharedBy
  ),
  await share.ls([])
)

If you'd like to use the auth lobby to accept, for ease of use like Fission Drive does, then you can create a share link with the share details we got earlier:

const link = webnative.fission.shareLink(shareDetails)
// "https://auth.fission.codes/#/share/sender-username/1/"

When sharing a file or directory with someone, they will receive the updates to those items due to how soft links work. Most file system methods work out of the box with soft links, such as get and read. But sometimes, you need to resolve them manually, which you can do with fs.resolveSymlink(). If you want to create a soft link manually, you can do that with:

await fs.symlink({
  at: webnative.path.directory("private", "Documents"),
  referringTo: {
    path: webnative.path.directory("private", "Photos")
  },
  name: "Pictures"
})

⚠️ For now soft links are read-only.

The referringTo object can be passed an optional username to create a soft link to a path in another user's filesystem.

Last updated