aboutsummaryrefslogtreecommitdiff
path: root/server.js
blob: 815e8ce2e7752da95b64535193ef6d0544e28aac (plain)
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
// 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 bogdir = homedir + '/.bogbook/bogs/'

if (!fs.existsSync(homedir + '/.bogbook/')) {
  fs.mkdirSync(homedir + '/.bogbook/')
}

if (!fs.existsSync(bogdir)){
  fs.mkdirSync(bogdir)
}

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))
          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')
                      })
                    }
                  })
                })
              } 
            })
          } 
        })
      }
    })
  })
})