Skip to content

Commit 0e00e78

Browse files
committed
wip pms
1 parent c29c84c commit 0e00e78

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ var createMessagesView = require('./views/messages')
1515
var createTopicsView = require('./views/topics')
1616
var createUsersView = require('./views/users')
1717
var createModerationView = require('./views/moderation')
18+
var createPrivateMessagesView = require('./views/private-messages')
1819
var swarm = require('./swarm')
1920

2021
var DATABASE_VERSION = 1
@@ -24,6 +25,7 @@ var MESSAGES = 'm'
2425
var TOPICS = 't'
2526
var USERS = 'u'
2627
var MODERATION = 'x'
28+
var PRIVATE_MESSAGES = 'p'
2729

2830
module.exports = Cabal
2931
module.exports.databaseVersion = DATABASE_VERSION
@@ -93,6 +95,11 @@ function Cabal (storage, key, opts) {
9395
this, this.modKey,
9496
sublevel(this.db, MODERATION, { valueEncoding: json }))
9597
)
98+
this.feed(function (feed) {
99+
self.kcore.use('privateMessages', createPrivateMessagesView(
100+
feed.secretKey,
101+
sublevel(self.db, PRIVATE_MESSAGES, { valueEncoding: json })))
102+
})
96103

97104
this.messages = this.kcore.api.messages
98105
this.channels = this.kcore.api.channels

views/private-messages.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
const {unbox} = require('../lib/crypto')
2+
var EventEmitter = require('events').EventEmitter
3+
4+
module.exports = function (mySecretKey, lvl) {
5+
var events = new EventEmitter()
6+
7+
return {
8+
maxBatch: 100,
9+
10+
map: function (msgs, next) {
11+
const self = this
12+
var ops = []
13+
var seen = {}
14+
var pending = 0
15+
msgs.forEach(function (msg) {
16+
if (msg.value.type !== 'encrypted') return
17+
18+
var jsonBuffer, res
19+
try {
20+
jsonBuffer = unbox(Buffer.from(msg.value.content, 'base64'), mySecretKey)
21+
if (!jsonBuffer) return // undecryptable
22+
res = JSON.parse(jsonBuffer.toString())
23+
} catch (e) {
24+
// skip unparseable messages
25+
return
26+
}
27+
28+
if (res.type !== 'private/text') return
29+
if (typeof res.timestamp !== 'number') return null
30+
if (!Array.isArray(res.content.recipients)) return null
31+
if (res.content.recipients.length <= 0) return null
32+
if (typeof res.content.text !== 'string') return null
33+
34+
const senderHexKey = msg.key
35+
const recipientHexKey = res.content.recipients[0]
36+
37+
// TODO: how to figure out my local feed key?
38+
// const otherPersonHexKey =
39+
console.log(self)
40+
41+
pending++
42+
43+
// add private convo recipient to list
44+
lvl.get('pm!' + recipientHexKey, function (err) {
45+
if (err && err.notFound) {
46+
if (!seen[recipient]) events.emit('add', channel)
47+
seen[recipient] = true
48+
49+
ops.push({
50+
type: 'put',
51+
key: 'pm!' + recipient,
52+
value: 1
53+
})
54+
}
55+
if (!--pending) done()
56+
})
57+
})
58+
if (!pending) done()
59+
60+
function done () {
61+
lvl.batch(ops, next)
62+
}
63+
},
64+
65+
api: {
66+
get: function (core, cb) {
67+
this.ready(function () {
68+
var channels = []
69+
lvl.createKeyStream({
70+
gt: 'channel!!',
71+
lt: 'channel!~'
72+
})
73+
.on('data', function (channel) {
74+
channels.push(channel.replace('channel!', ''))
75+
})
76+
.once('end', function () {
77+
cb(null, channels)
78+
})
79+
.once('error', cb)
80+
})
81+
},
82+
83+
events: events
84+
},
85+
86+
storeState: function (state, cb) {
87+
state = state.toString('base64')
88+
lvl.put('state', state, cb)
89+
},
90+
91+
fetchState: function (cb) {
92+
lvl.get('state', function (err, state) {
93+
if (err && err.notFound) cb()
94+
else if (err) cb(err)
95+
else cb(null, Buffer.from(state, 'base64'))
96+
})
97+
},
98+
}
99+
}
100+
101+
// Either returns a well-formed chat message, or null.
102+
function sanitize (msg) {
103+
return msg
104+
}

0 commit comments

Comments
 (0)