1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
// static server (8089)
var http = require('http')
var serve = require('ecstatic')
var open = require('open')
http.createServer(
serve({ root: __dirname})
).listen(8089)
open('http://localhost:8089')
// ws server (8080)
var bog = require('./bog')
var WS = require('ws')
var fs = require('fs')
var nacl = require('tweetnacl')
nacl.util = require('tweetnacl-util')
var homedir = require('os').homedir()
var sanitize = require('sanitize-filename')
var bogdir = homedir + '/.bogbook/bogs/'
var blobdir = homedir + '/.bogbook/blobs/'
if (!fs.existsSync(homedir + '/.bogbook/')) {fs.mkdirSync(homedir + '/.bogbook/')}
if (!fs.existsSync(bogdir)){fs.mkdirSync(bogdir)}
if (!fs.existsSync(blobdir)){fs.mkdirSync(blobdir)}
var wserve = new WS.Server({ port: 8080 })
bog.keys().then(key => {
wserve.on('connection', function (ws) {
ws.on('message', function (message) {
var req = JSON.parse(message)
if (req.sendpub) {
ws.send(key.publicKey)
}
else {
bog.unbox(req.box, req.requester, key).then(unboxed => {
var unboxedreq = JSON.parse(nacl.util.encodeUTF8(unboxed))
//console.log(unboxedreq)
if (unboxedreq.blobFile) {
var openedimg = nacl.sign.open(nacl.util.decodeBase64(unboxedreq.blobFile), nacl.util.decodeBase64(unboxedreq.author.substring(1)))
if (openedimg) {
//console.log(openedimg)
fs.writeFileSync(blobdir + '/' + sanitize(unboxedreq.blob), unboxedreq.blobFile, 'UTF-8')
console.log('received blob ' + unboxedreq.blob + ' from ' + req.requester + ' and saved to blobs folder')
}
}
if (unboxedreq.blob) {
console.log(req.requester + ' has requested the blob ' + unboxedreq.blob)
var blobExists = fs.existsSync(blobdir + '/' + sanitize(unboxedreq.blob))
if (unboxedreq.needs) {
console.log(req.requester + ' needs ' + unboxedreq.blob + ' do we have it?')
if (blobExists) {
console.log('We have it, so send it to the client')
var blobToSend = fs.readFileSync(blobdir + '/' + sanitize(unboxedreq.blob), 'UTF-8')
var sendblob = {
blob: unboxedreq.blob,
blobFile: blobToSend
}
console.log(sendblob)
bog.box(JSON.stringify(sendblob), req.requester, key).then(boxed => {
var obj = {
requester: key.publicKey,
box: boxed
}
ws.send(JSON.stringify(obj))
})
}
} else {
console.log(req.requester + ' has ' + unboxedreq.blob + ' do we need it?')
if (!blobExists) {
console.log('We need it, so request it from the client')
var blobreq = { blob: unboxedreq.blob, needs: true }
bog.box(JSON.stringify(blobreq), req.requester, key).then(boxed => {
var obj = {
requester: key.publicKey,
box: boxed
}
ws.send(JSON.stringify(obj))
})
}
}
}
if (unboxedreq.seq === 0) {
console.log(req.requester + ' asked the full log of ' + unboxedreq.author)
fs.readFile(bogdir + unboxedreq.author, 'UTF-8', function (err, data) {
if (data) {
//var feed = JSON.stringify(data)
var feed = data
bog.box(feed, req.requester, key).then(boxed => {
var obj = {
requester: key.publicKey,
box: boxed
}
ws.send(JSON.stringify(obj))
console.log('Sent full log of ' + unboxedreq.author + ' to ' + req.requester)
})
}
})
}
if (unboxedreq.seq) {
console.log(req.requester + ' asked for feed ' + unboxedreq.author + ' after sequence ' + unboxedreq.seq)
// check to see if we have the feed on disk
fs.readFile(bogdir + unboxedreq.author, 'UTF-8', function (err, data) {
if (data) {
// TODO open the latest message, and check the sequence number
var feed = JSON.parse(data)
bog.open(feed[0]).then(msg => {
if (unboxedreq.seq === msg.seq) {
console.log(unboxedreq.author + '\'s feed is identical, sending nothing to client')
}
if (unboxedreq.seq > msg.seq) {
// right now the client is still sending the entire log, which works just fine but isn't optimal
console.log('client feed is longer, requesting diff from client')
var reqdiff = JSON.stringify({author: unboxedreq.author, seq: msg.seq})
bog.box(reqdiff, req.requester, key).then(boxed => {
var obj = {
requester: key.publicKey,
box: boxed
}
ws.send(JSON.stringify(obj))
})
}
if (unboxedreq.seq < msg.seq) {
console.log('client feed is shorter, sending diff to client')
var diff = JSON.stringify(feed.slice(0, msg.seq - unboxedreq.seq))
bog.box(diff, req.requester, key).then(boxed => {
var obj = {
requester: key.publicKey,
box: boxed
}
ws.send(JSON.stringify(obj))
})
}
})
} else {
// if we don't have the feed, request the feed from the client and save
console.log('We don\'t have the log on the server, requesting log from ' + req.requester )
var reqwhole = JSON.stringify({author: unboxedreq.author, seq: 0})
bog.box(reqwhole, req.requester, key).then(boxed => {
var obj = {
requester: key.publicKey,
box: boxed
}
ws.send(JSON.stringify(obj))
})
}
})
} else if (Array.isArray(unboxedreq)) {
// first check to make sure that we have an entire log
bog.open(unboxedreq[0]).then(msg => {
if (msg.seq === unboxedreq.length) {
fs.writeFile(bogdir + msg.author, JSON.stringify(unboxedreq), 'UTF-8', function (err, success) {
console.log('Saved full log of ' + msg.author + ' sent by ' + req.requester)
})
} if (msg.seq > unboxedreq.length) {
fs.readFile(bogdir + msg.author, 'UTF-8', function (err, data) {
var feed = JSON.parse(data)
bog.open(feed[0]).then(lastmsg => {
if (unboxedreq.length + lastmsg.seq === msg.seq) {
var newlog = unboxedreq.concat(feed)
fs.writeFile(bogdir + msg.author, JSON.stringify(newlog), 'UTF-8', function (err, success) {
console.log('combined existing feed of ' + msg.author + ' with diff and saved to server')
})
}
})
})
}
})
}
})
}
})
})
})
|