@ssb-graphql/whakapapa
Version:
GraphQL types and resolvers for the ssb-whakapapa plugin
94 lines (78 loc) • 2.74 kB
JavaScript
const get = require('lodash.get')
const pull = require('pull-stream')
const { promisify: p } = require('util')
const { where, slowEqual, toPullStream } = require('ssb-db2/operators')
module.exports = function TombstoneProfileAndLinks (ssb) {
return function tombstoneProfileAndLinks (id, details = {}, cb) {
if (cb === undefined) return p(tombstoneProfileAndLinks)(id, details)
tombstoneProfile(id, details, (err) => {
if (err) return cb(err)
tombstoneLinksOnId(id, details, (err) => {
if (err) return cb(err)
cb(null, id)
})
})
}
function tombstoneProfile (id, details, cb) {
ssb.get({ id, private: true }, (err, val) => {
if (err) return cb(err)
const { type, recps } = val.content
if (!type) return cb(new Error(`cannot decrypt ${id}`))
const crut = get(ssb.profile, getTypePath(type, recps))
if (!crut) return cb(new Error(`unknown profile type ${type}`))
// find any whakapapa/views that this
findWhakapapaViewsWithFocus(id, recps, (err, views) => {
if (err) return cb(err)
if (views && views.length) return cb(new Error('This profile is the root person of a whakapapa and cannot be deleted!'))
crut.tombstone(id, details, cb)
})
})
}
function findWhakapapaViewsWithFocus (id, recps, cb) {
ssb.whakapapa.view.list({
groupId: recps && recps[0],
filter (whakapapa) {
return (
whakapapa.focus === id &&
whakapapa.tombstone === null
)
}
}, cb)
}
function tombstoneLinksOnId (id, details, cb) {
pull(
ssb.db.query(
where(
slowEqual('value.content.tangles.link.root', null)
),
toPullStream()
),
pull.filter(m => m.value.content.type.startsWith('link/')),
pull.filter(m => (
m.value.content.parent === id ||
m.value.content.child === id
)),
pull.map(m => m.key),
pull.asyncMap((linkId, cb) => {
ssb.whakapapa.link.get(linkId, (err, link) => {
if (err) return cb(null)
if (link.tombstone) return cb(null) // dont tombstone something thats already tombstoned
ssb.whakapapa.link.tombstone(linkId, details, (err) => {
if (err) console.error('tombstone link failed', linkId, err)
cb(null)
// NOTE this currently swallows all failures to tombstone
})
})
}),
pull.collect(cb)
)
}
}
// copied from @ssb-graphql/profile
function getTypePath (typeStr, recps) {
const typePath = typeStr.split('/').filter(t => t !== 'profile')
if (typePath.length === 1) {
typePath.push(recps ? 'group' : 'public')
}
return typePath
}