📄 | LICENSE |
📄 | README.md |
📄 | cap.js |
📄 | index.js |
📄 | package.json |
📁 | test |
📄 | util.js |
📄 | valid.js |
user-invites
when ssb was younger, we created the current invite system, henceforth in this document referred to as the "followbot" system. special peers called "pubs" can create tokens called "invite codes". The invite code allows a new person to connect to the pub, and request a follow.
This generally worked fairly well, but had some problems:
- not clear who invited who.
- people were confused about what a "pub" was
- sometimes pubs failed to follow back.
- some pubs more inviting than others "too open"
- hard to tell if growth was word of mouth or not
solution: user-invites
These are invites created directly by users to directly invite one new person.
- host user creates invite, publishes stub, sends invite to guest
- guest connects to pub, requests invite message, which contains host identity.
- guest publishes accept message
- guest passes accept message to pub directy
- pub now replicates guest, considering them friend of host, and publishes a "confirm" containing the accept message.
- other peers can strongly link invite with accept via confirm.
example
Alice wishes to invite Bob to her corner of the ssb network. But she is does not have a pub server. She creates a user invite, indicating that she is creating an invite. This is just a message on her feed.
var seed = random(32) //32 bytes of randomness
var invite_key = ssbKeys.generate(null, seed)
var invite_cap = require('ssb-config').caps.invite
alice_sbot.publish(ssbKeys.signObj({
type: 'invite',
invite: invite_key.id,
host: alice.id,
//optional fields
reveal: box(message_to_be_revealed, hash(hash(seed))),
private: box(message_for_bob, hash(seed))
}, invite_cap, invite_key),
function (err, invite_msg) {
...
})
reveal
and private
are optional, and will
be discussed later.
also note, the the invite is self-signed, to proove
that alice created the invite code, and so that no one
else can claim they invited alice's friend.
The signature has an invite_cap
so that it cannot be confused with another type of signature.
TODO alice encodes the seed, the message id, and the addresses of some pubs that are likely to replicate bob. this is called the "invite code"
she then gives the invite code to bob via a channel she already trusts, say, a 1:1 chat app.
bob then connects to one of the pubs in the invite code, using the guest id derived from the seed (which the pub will recognise as alice's guest)
bob then requests the invite message, and probably alice's feed. if the invite has reveal and public fields, bob decrypts them.
if bob accepts the invite, bob then creates an "invite/accept" message, which is a proof that he has the seed, and knows who's invite he is accepting.
var invite_key = ssbKeys.generate(null, seed)
var invite_cap = require('ssb-config').caps.invite
sbot_bob.publish(ssbKeys.signObj({
type: 'invite/accept',
receipt: getId(invite_msg), //the id of the invite message
id: bob.id, //the id we are accepting this invite as.
//if the invite has a reveal, key must be included.
key: hash(hash(seed))
}, invite_cap, invite_key),
function (err, invite_accept_msg) {
...
})
This is then passed to the pub, who verifies it, and if is correct, posts a new message containing it.
sbot_pub.publish({
type: 'invite/confirm',
embed: invite_accept_msg //embed the whole message.
}, function (err, invite_confirm_msg) {
...
})
the pub just reposts the whole invite_accept message that bob created. this makes the message available for other peers to validate, since they do not follow bob yet.
the pub now knows that bob and alice are friends, and will start replicating bob. Other friends of alice who replicate the pub will also see this, and they will also start replicating bob. Thus alice's friends can welcome bob, knowing it's a friend of alice, even if alice is offline.
reveal & private
There are two optional encrypted fields on an invite.
reveal
and private
. The private field contains
a private message from the host that the guest reads
when accepting the invite. The private field is
intended to hold a private welcome message from the host.
The reveal feed is more
interesting. To accept the invite, the guest must
provide the decryption key to the reveal field,
otherwise their accept message is ignored.
The reveal field is intended to hold a message from
the host to their other peers, it's about their guest,
but it's for their other friends.
"hey everyone, this is bob, he's really awesome at growing mushrooms!"
Most importantly, this message can be used to assign
a name for bob. Also importantly, the reveal message
is secret until bob accepts the invite. This avoids
revealing anything about bob without his consent
(he may choose not to accept the invite if he disagrees
with what alice says about him)
License
MIT
Built with git-ssb-web