ssb-whakapapa

an ssb-server plugin for creating, reading, managing relationship links in scuttlebutt


Keywords
scuttlebutt, whakapapa, relationships, ssb
License
AGPL-3.0
Install
npm install ssb-whakapapa@4.0.0

Documentation

ssb-whakapapa

An ssb-server plugin for creating, reading, updating relationships between profiles

Example Usage

const Server = require('ssb-server')
const Config = require('ssb-config/inject')

const config = Config({})

const server = Server
  .use(require('ssb-master'))
  .use(require('ssb-backlinks'))
  .use(require('ssb-whakapapa')) // <<<<<<
  .call(null, config)

const details = {
  child: '%P5r79KsntEGPMp0Zd24bvfDBMtfx1SADMEE7yxBdVVw=.sha256',
  parent: '%4BmROhXcW6H4VyATrIj7uOWqHyW5q5jFZpDHo5RofSc=.sha256',
}

const opts = {
  relationshipType: { set: 'birth' },

  recps: [
    '@ye+QM09iPcDJD6YvQYjoQc7sLF/IFhmNbEqgdzQo3lQ=.ed25519'
  ]
}

server.whakapapa.child.create(details, opts, (err, relationshipId) => {
  // ...
})
// later:
server.whakapapa.get('%P5r79KsntEGPMp0Zd24bvfDBMtfx1SADMEE7yxBdVVw=.sha256', (err, data) => {
  console.log(data)
  // => {
  //   profileId: '%P5r79KsntEGPMp0Zd24bvfDBMtfx1SADMEE7yxBdVVw=.sha256',
  //   parents: [
  //     {
  //       profileId: '%4BmROhXcW6H4VyATrIj7uOWqHyW5q5jFZpDHo5RofSc=.sha256',
  //       relationshipId: '%W5q4BmROhXcW6H4VyATrIj7uOWqHy5jFZpDHo5RofSc=.sha256',
  //       relationshipType: 'birth',
  //       legallyAdopted: null // null means it hasnt been set
  //     }
  //   ],
  //   children: []
  // }
})

API

Relationships:

Views:

server.whakapapa.get

Get children and parents of a particular profile.

server.whakapapa.get(ProfileId, cb)

  • ProfileId String - the id for a profile
  • cb Function - a callback of signature (err, data)

data format

{
  parents: [
    {
      profileId: '%4BmROhXcW6H4VyATrIj7uOWqHyW5q5jFZpDHo5RofSc=.sha256',
      relationshipId: '%47uOWqHyW5q5jFZpDHo5RofBmROhXcW6H4VyATrIjSc=.sha256',
      relationshipType: 'birth',
      legallyAdopted: null
    },
    { 
      profileId: '%r86qOq2KNY3GlifR6UgQaB05ZfXmHlnxxoFlyi9OI0A=.sha256'
      relationshipId: '%W5q5j47uOWqHyFZpDHo5RofBmROhXcW6H4VyATrIjSc=.sha256',
      relationshipType: null, // this means relationshipType hasnt been set
      legallyAdopted: null
    }
  ],
  children: [
    {
      profileId: '%pCt2QB3ZxZEsKIYvxGI9QBmytrUNZfuuRbNk8i0V7ug=.sha256',
      relationshipId: '%yFZpDHo5RoW5q5j47uOWqHfBmROhXcW6H4VyATrIjSc=.sha256',
      relationshipType: 'whangai',
      legallyAdopted: false
    }
  ]
}

server.whakapapa.child.create

Creates a new updateable message of type whakapapa/child connecting two profiles - a parent and a child.

server.whakapapa.child.create({ child, parent }, opts, cb)

  • child String a scuttlebutt MessageId pointing to a profile root
  • parent String a scuttlebutt MessageId pointing to a profile root
  • opts Object - describes the values to set on that relationship and who can read it.
  • cb Function - a callback of signature (err, relationshipId) where relationshipId is the id of the relationship which has just been created

opts format

{
  relationshipType: { set: ParentType }, // optional
  legallyAdopted: { set: Boolean }       // optional

  recps: [ FeedId ]                      // optional
}
  • MessageId is scuttlebutt message cypherlink e.g. %4BmROhXcW6H4VyATrIj7uOWqHyW5q5jFZpDHo5RofSc=.sha256
  • relationshipType is any of 'birth' | 'adopted' | 'whangai' | 'unknown'
  • legallyAdopted should only be set if relationshipType is 'adopted' or 'whangai'
  • recps is an Array of FeedId (e.g. '@ye+QM09iPcDJD6YvQYjoQc7sLF/IFhmNbEqgdzQo3lQ=.ed25519'). If this is provided this relationship will automatically be encrypted so only the mentioned parties will be able to see this. (NOTE - you cannot change this later)

Notes If you don't want to add any optional opts, set opts to null or {}

:construction: TODO

  • add GroupId to recps once we have private-groups released
  • add tombstone property (perhaps a simple-set of people who have tombstoned it) to enable deletion
  • add some way to validate whakapapa links
    • e.g. an approval system so that kaitiaki (custodians) at each end of the relationship can approve the link?
    • need to make sure that can't change pointer for child / parent after an "approval" of link

server.whakapapa.child.update

This updates a child relationship (not the child themself).

server.whakapapa.child.update(relationshipId, opts, cb)

  • relationshipId MessageId - the root key of the relationship
  • opts Object - same as in child.create, except recps is set for you based on what the first message was.
  • cb function - callback with signature (err)

:construction: TODO

  • needed for tombstoning

server.whakapapa.view.get

Fetch a "view" of whakapapa - this is a minimal record which stores the sdetails needed to construct a particular perspective on a graph of relationships.

e.g. we might want to see all the descendants of a particular ancestor. To do this we store the profileId of that ancestor and the mode of drawing (down!). We might also include preferences about whether to include whangai or adopted descendants for example.

server.whakapapa.view.get(viewId, cb)

  • viewId MessageId - the id of the root message of a view
  • cb function - a callback of signature (err, data), where data is an Object with properties:
    • name String - the name of this whakapapa view
    • description String - the name of this whakapapa view
    • ignoredProfiles Array - an array of ProfileIds which have been marked to ignore (don't render these please). Returns [] if there are none.
    • focus ProfileId - the id of the profile we start from
    • mode String - the way to draw the graph. (can be 'descendants' | 'ancestors')
    • tombstone Object - date and reason

If any of these are not set, these properties will still be present, but the values will be null

server.whakapapa.view.create

Creates a new message of type whakapapa/view

server.whakapapa.view.create(details, cb)

  • details Object - contains information to start off view
  • cb function - a form (err, viewId)

The expected form of details is :

{
  name: { set: String },
  description: { set: String },          // optional
  focus: { set: ProfileId }, 
  mode: { set: Mode },
  image: { set: Image },          // optional
  recps: [ FeedId, ... ],          // optional
  tombstone: { set: Tombstone }   // optional
  ignoredProfiles: { add: [ProfileId] } // optional
}

Notes:

  • Mode can be 'descendants' | 'ancestors'
  • Image is an Object of form { blob: '&07xxrn0wWbtRx/gp4IF7THPeWZUT1LWt93IVHTbitFE=.sha256', mimeType: 'image/png' }
  • recps is a special field which encrypts the view (and all subsequent updates) to a specified set of FeedIds
  • Tombstone is an Object of form { reason: String, date: UnixTime }

TODO - tombstone

server.whakapapa.view.update

server.whakapapa.view.update(viewId, details, cb)

  • viewId MessageId - the id of the view to update
  • details Object - same as in view.create, except
    • ignoredProfiles can also be { ignoredProfiles: { remove: [ProfileId] } } for updates
    • recps is inherrited from the create message (root), so setting it here does nothing.
  • cb function - callback with signature (err)