git ssb

0+

Dominic / ssb-peer-invites



Commit 4f6a9b08479bfd25c838d25a7a44d99b99fe57e7

comment edge cases. rememer guest ids, incase they need to reconfirm. also do not leave undefined properties in messages, because it breaks deepEqual

Dominic Tarr committed on 12/16/2018, 2:10:06 AM
Parent: 5b1f218a3f28e90d43dcf6b0798da47536ee7fb7

Files changed

index.jschanged
types.jschanged
valid.jschanged
index.jsView
@@ -49,18 +49,27 @@
4949 var init = false
5050 var layer = sbot.friends.createLayer('user-invites')
5151
5252 var caps = config.caps || {}
53 + var initial = {invites: {}, accepts: {}, hosts: {}, guests: {}}
5354 caps.userInvite = caps.userInvite || require('./cap')
5455
5556 function reduce (acc, data, _seq) {
56- if(!acc) acc = {invited: {}, invites:{}, accepts: {}, hosts: {}}
57 + if(!acc) acc = initial
5758 var msg = data.value
5859 var invite, accept
5960 if(types.isInvite(msg, caps)) {
6061 //TODO: validate that this is a msg we understand!
6162 invite = msg
6263 accept = acc.accepts[data.key]
64 +
65 + //remember guest ids, so that you can process pub messages.
66 + //this is necessary to confirm invites here the guest failed before they received
67 + //the confirmation, and do not realize they are confirmed yet. they'll try again later.
68 +
69 + //id rather not have this here. it's gonna bloat. better a different kind of index.
70 + //can fix this later though.
71 + acc.guests[data.value.content.invite] = true
6372 }
6473 else if(types.isAccept(msg, caps)) {
6574 accept = msg
6675 invite = acc.invites[accept.content.receipt]
@@ -98,9 +107,8 @@
98107
99108 return acc
100109 }
101110
102- var initial = {invites: {}, accepts: {}, hosts: {}}
103111 var state
104112 //a hack here, so that we can grab a handle on invites.value.set
105113 var invites = sbot._flumeUse('user-invites', function (log, name) {
106114 var _invites = Reduce(2, reduce, null, null, initial)(log, name)
@@ -122,18 +130,18 @@
122130 })
123131
124132 sbot.auth.hook(function (fn, args) {
125133 var id = args[0], cb = args[1]
134 + //currently a problem here where message may be confirmed,
135 + //but guest didn't get the welcome yet. they need to be able to connect
136 + //and request it again.
126137 invites.get(function (err, v) {
127138 if(err) return cb(err)
128- for(var k in v.invites) {
129- if(v.invites[k].content.invite === id) {
130- return cb(null, {
131- allow: ['userInvites.getInvite', 'userInvites.confirm'],
132- deny: null
133- })
134- }
135- }
139 + if(v.guests[id])
140 + return cb(null, {
141 + allow: ['userInvites.getInvite', 'userInvites.confirm'],
142 + deny: null
143 + })
136144 fn.apply(null, args)
137145 })
138146 })
139147
@@ -222,17 +230,9 @@
222230 //before this write completes, it will write twice, so just return an error.
223231 if(accepted[invite_id]) return cb(new Error('race condition: try again soon'))
224232
225233 accepted[invite_id] = true
226- sbot.publish({
227- type: 'user-invite/confirm',
228- embed: accept,
229- //second pointer back to receipt, so that links can find it
230- //(since it unfortunately does not handle links nested deeper
231- //inside objects. when we look up the message,
232- //confirm that content.embed.content.receipt is the same)
233- receipt: accept.content.receipt
234- }, function (err, data) {
234 + sbot.publish(I.createConfirm(accept), function (err, data) {
235235 delete accepted[invite_id]
236236 cb(err, data.value)
237237 })
238238 })
types.jsView
@@ -49,9 +49,14 @@
4949
5050 exports.isConfirm = function (msg) {
5151 return isObject(msg) && isObject(msg.content) && (
5252 'user-invite/confirm' === msg.content.type &&
53- exports.isAccept(msg.content.embed)
53 + exports.isAccept(msg.content.embed) &&
54 + //second pointer back to receipt, so that links can find it
55 + //(since it unfortunately does not handle links nested deeper
56 + //inside objects. when we look up the message,
57 + //confirm that content.embed.content.receipt is the same)
58 + msg.content.embed.content.receipt === msg.content.receipt
5459 )
5560 }
5661
5762
valid.jsView
@@ -66,14 +66,16 @@
6666 var keys = ssbKeys.generate(null, seed) //K
6767 if(keys.id != msg.content.invite)
6868 throw code(new Error('seed does not match invite'), 'seed-must-match-invite')
6969 var inviteId = '%'+ssbKeys.hash(JSON.stringify(msg, null, 2))
70- return ssbKeys.signObj(keys, caps.userInvite, {
70 + var content = {
7171 type: 'user-invite/accept',
7272 receipt: inviteId,
73- id: id,
74- key: msg.content.reveal ? u.hash(u.hash(seed)).toString('base64') : undefined
75- })
73 + id: id
74 + }
75 + if(msg.content.reveal)
76 + content.key = u.hash(u.hash(seed)).toString('base64')
77 + return ssbKeys.signObj(keys, caps.userInvite, content)
7678 }
7779
7880 exports.verifyAcceptOnly = function (accept, caps) {
7981 if(!isObject(caps)) throw new Error('caps *must* be provided')
@@ -115,5 +117,18 @@
115117 //an ordinary message, so does not use hmac_key
116118 return reveal || true
117119 }
118120
121 +exports.createConfirm = function (accept) {
122 + return {
123 + type: 'user-invite/confirm',
124 + embed: accept,
125 + //second pointer back to receipt, so that links can find it
126 + //(since it unfortunately does not handle links nested deeper
127 + //inside objects. when we look up the message,
128 + //confirm that content.embed.content.receipt is the same)
129 + receipt: accept.content.receipt
130 + }
131 +}
119132
133 +
134 +

Built with git-ssb-web