statebus 7.0.32 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/server-library.js CHANGED
@@ -1,12 +1,9 @@
1
1
  var fs = require('fs'),
2
2
  util = require('util')
3
3
 
4
- var braidify = require('braid-http').http_server
5
-
6
4
 
7
5
  function default_options (bus) { return {
8
6
  port: 'auto',
9
- backdoor: null,
10
7
  client: (c) => {c.shadows(bus)},
11
8
  file_store: {save_delay: 250, filename: 'db', backup_dir: 'backups', prefix: '*'},
12
9
  sync_files: [{state_path: 'files', fs_path: null}],
@@ -14,9 +11,11 @@ function default_options (bus) { return {
14
11
  certs: {private_key: 'certs/private-key',
15
12
  certificate: 'certs/certificate',
16
13
  certificate_bundle: 'certs/certificate-bundle'},
17
- connections: {include_users: true, edit_others: true},
14
+ connections: {include_users: true, edit_others: true}, // Only for websockets
15
+ websocket: false,
18
16
  websocket_path: '_connect_to_statebus_',
19
- __secure: false
17
+ free_cors: true,
18
+ __secure: false // Only for websocket for connections state. Deprecate soon.
20
19
  }}
21
20
 
22
21
  function set_options (bus, options) {
@@ -53,41 +52,44 @@ function import_server (bus, make_statebus, options)
53
52
  || require('fs').existsSync(bus.options.certs.certificate)
54
53
  || require('fs').existsSync(bus.options.certs.certificate_bundle))
55
54
 
56
- function c (client, conn) {
57
- client.honk = bus.honk
58
- client.serves_auth(conn, master)
59
- bus.options.client && bus.options.client(client, conn)
60
- }
61
- if (!bus.options.client) c = undefined // no client bus when programmer explicitly says so
62
-
63
- if (bus.options.file_store)
64
- bus.file_store()
55
+ // Create the client
56
+ if (bus.options.client)
57
+ // Todo: rewrite this func
58
+ bus.custom_clients = (client, client_id) => {
59
+ client.honk = bus.honk
60
+ client.serves_auth(master)
61
+ bus.options.client && bus.options.client(client)
62
+ }
65
63
 
66
- // ******************************************
67
- // ***** Create our own http server *********
64
+ // Create HTTP server
68
65
  bus.make_http_server({port: bus.options.port, use_ssl})
69
- bus.sockjs_server(this.http_server, c) // Serve via sockjs on it
66
+ if (bus.options.websocket)
67
+ bus.sockjs_server(this.http_server) // Serve via sockjs on it
70
68
  var express = require('express')
71
69
  bus.express = express()
72
70
  bus.http = express.Router()
73
71
  bus.install_express(bus.express)
74
72
 
73
+ // User will put his routes in here
74
+ bus.express.use(bus.http)
75
+
76
+ // Connect bus to the HTTP server
77
+ bus.express.use(bus.http_in)
78
+
75
79
  // use gzip compression if available
76
80
  try { bus.http.use(require('compression')())
77
81
  console.log('Enabled http compression!') } catch (e) {}
78
82
 
83
+ // Initialize storage
84
+ if (bus.options.file_store)
85
+ bus.file_store()
86
+
79
87
  // Initialize file sync
80
88
  ; (bus.options.sync_files || []).forEach( x => {
81
89
  if (require('fs').existsSync(x.fs_path || x.state_path))
82
90
  bus.sync_files(x.state_path, x.fs_path)
83
91
  })
84
92
 
85
- // User will put his routes in here
86
- bus.express.use(bus.http)
87
-
88
- // Connect bus to the HTTP server
89
- bus.express.use(bus.http_in)
90
-
91
93
  // Serve Client Coffee
92
94
  bus.serve_client_coffee()
93
95
 
@@ -124,130 +126,156 @@ function import_server (bus, make_statebus, options)
124
126
  }
125
127
  return handlers.length
126
128
  }
127
-
128
- // Back door to the control room
129
- if (bus.options.backdoor) {
130
- bus.make_http_server({
131
- port: bus.options.backdoor,
132
- name: 'backdoor_http_server',
133
- use_ssl: use_ssl
134
- })
135
- bus.sockjs_server(this.backdoor_http_server)
136
- }
137
129
  },
138
130
 
131
+
139
132
  // Connect HTTP GET and PUT to our Get and Set
140
133
  http_in: function (req, res, next) {
134
+ // Log this request!
141
135
  if (bus.honk)
142
- console.log(req.method, req.url, req.headers.subscribe
136
+ console.log('IN:', req.method, decodeURIComponent(req.url), req.headers.subscribe
143
137
  ? 'Subscribe: ' + req.headers.subscribe : '')
144
138
 
145
- braidify(req, res)
146
-
147
- // If this requests knows about Braid then we presume the programmer
139
+ // If this request knows about Braid then we presume the programmer
148
140
  // knows that any client might make this cross-origin request.
149
141
  if (req.headers.version || req.headers.parents || req.headers.subscribe
150
142
  || req.headers.peer || req.headers['put-order']
151
- || req.method === 'OPTIONS')
143
+ || req.method === 'OPTIONS' || bus.options?.free_cors)
152
144
  free_the_cors(req, res)
153
145
  if (req.method === 'OPTIONS')
154
146
  return
155
147
 
156
- // Initialize new clients with an id. We put the client id on
157
- // req.client, and also in a cookie for the browser to see.
158
- req.peer = //req.headers.peer ||
159
- require('cookie').parse(req.headers.cookie || '').peer
160
- if (!req.peer) {
161
- req.peer = (Math.random().toString(36).substring(2)
162
- + Math.random().toString(36).substring(2)
163
- + Math.random().toString(36).substring(2))
164
-
165
- res.setHeader('Set-Cookie', 'peer=' + req.peer
166
- + '; Expires=21 Oct 2055 00:0:00 GMT;')
148
+ // Give up on methods we can't handle
149
+ if (!['GET', 'PUT', 'DELETE'].includes(req.method)) {
150
+ res.setHeader('Allow', 'GET, PUT, DELETE')
151
+ res.statusCode = 405
152
+ res.end()
153
+ return
167
154
  }
168
155
 
169
- // Handle the GET or PUT request!
170
- if (req.method === 'GET') {
171
- var key = req.url.substr(1)
172
-
173
- // Make a temporary client bus
174
- var cbus = bus.bus_for_http_client(req, res)
156
+ // Braidify the req and res
157
+ require('braid-http').http_server(req, res)
175
158
 
159
+ // Initialize new clients with an id. We put the client id on
160
+ // req.client, and also in a cookie for the browser to see.
161
+ var client_id = req.headers.peer ||
162
+ require('cookie').parse(req.headers.cookie || '').peer
163
+
164
+ if (!client_id)
165
+ client_id = (Math.random().toString(36).substring(2)
166
+ + Math.random().toString(36).substring(2)
167
+ + Math.random().toString(36).substring(2))
168
+
169
+ // Add peer to response cookie, so client knows we've named it
170
+ var expires = new Date()
171
+ expires.setFullYear(expires.getFullYear() + 20)
172
+ res.setHeader('Set-Cookie', 'peer=' + client_id
173
+ + '; Expires=' + expires.toUTCString() + ';')
174
+
175
+ // Decode the key
176
+ var key = decodeURIComponent(req.url.substr(1))
177
+
178
+ // Make the client bus
179
+ var client_bus = bus.client_bus_for(client_id)
180
+
181
+ // Handle a GET!
182
+ if (req.method === 'GET') {
176
183
  if (req.subscribe)
177
- res.startSubscription({ onClose: end_subscription })
184
+ res.startSubscription({ onClose: close_subscription })
178
185
  else
179
186
  res.statusCode = 200
180
187
 
181
- // We only return JSON
188
+ // We assume all content is JSON
182
189
  res.setHeader('Content-Type', 'application/json')
183
190
 
184
- // console.log('http_in: doing cbus.get(', key, ')')
185
-
186
- var send_to_client = (o, t) => {
187
- // console.trace('http_in: Sending update of', key)
188
- var body = to_http_body(o)
191
+ function send_update (obj, t) {
192
+ var body = to_http_body(obj)
193
+ // console.log('http_in: Sending update of', body)
189
194
 
190
- // Note: if body === undefined, we need to send the
191
- // equivalent of a 404. This is missing in braid spec:
192
- // https://github.com/braid-org/braid-spec/issues/110
193
- res.sendVersion({body: body || 'null'})
195
+ res.sendUpdate({
196
+ body,
197
+ // If body === undefined, send 404
198
+ status: body === undefined ? 404 : 200
199
+ })
194
200
 
195
201
  // And shut down the connection if there's no subscription
196
202
  if (!req.subscribe)
197
- end_subscription()
203
+ close_subscription()
198
204
  }
199
205
 
200
- function end_subscription () {
201
- cbus.forget(key, send_to_client)
206
+ function close_subscription () {
207
+ client_bus.forget(key, send_update)
202
208
  res.end()
203
- cbus.http_unsubscribe(req)
204
209
 
205
- let peer = req.headers.peer
206
- if (cbus.http_callbacks)
207
- delete cbus.http_callbacks[JSON.stringify({peer, key})]
210
+ delete client_bus.dialogues[req.headers.dialogue]
208
211
  }
209
212
 
210
213
  // If we have a peer id, then register this callback at that peer,
211
214
  // so it can avoid getting its own PUT versions echoed back to
212
215
  // itself.
213
- if (req.headers.peer) {
214
- if (!cbus.http_callbacks)
215
- cbus.http_callbacks = {}
216
- let peer = req.headers.peer
217
- cbus.http_callbacks[JSON.stringify({peer, key})]
218
- = send_to_client
219
- }
216
+ if (req.headers.dialogue)
217
+ client_bus.dialogues[req.headers.dialogue] = send_update
220
218
 
221
219
  // And issue the get!
222
- cbus.get(key, send_to_client)
220
+ client_bus.get(key, send_update)
223
221
  }
224
222
 
223
+ // Handle a PUT!
225
224
  else if (req.method === 'PUT') {
226
225
 
226
+ // Grab the version(s)
227
+ var t = {
228
+ version: req.version || client_bus.new_version(),
229
+ parents: req.parents
230
+ }
231
+
227
232
  // Maybe the new state is expressed in patches
228
233
  if (req.headers.patches || req.headers['content-range']) {
229
234
 
230
235
  var patches = req.patches().then(patches => {
231
- console.log("...and we see these patches:", patches)
232
- var cbus = bus.bus_for_http_client(req, res)
233
- var key = req.url.substr(1)
234
- cbus.get_once(key, (obj) => {
235
- cbus.set(key, {patches})
236
+
237
+ // Presume all patch contents are text
238
+ t.patches = patches.map(patch => ({
239
+ ...patch,
240
+ content: patch.content_text
241
+ }))
242
+ // console.log("...and we see these patches:", patches)
243
+
244
+ // Fetch our current state on the bus
245
+ client_bus.get_once(key, (obj) => {
246
+ // ...and apply the patches to it
247
+ client_bus.set(key, t)
248
+
249
+ // Todo: Make a statebus auto-fetch current state when
250
+ // patching so that I don't need to manually fetch it
251
+ // before applying a patch.
252
+
253
+ // Todo: only send success once transaction has
254
+ // validated. Handle aborts, too.
236
255
  res.sendStatus(200)
237
- console.log('We just processed a patch!')
256
+ // console.log('We just processed a patches!')
238
257
  })
239
258
  })
240
- } else {
241
- // Otherwise, we assume the body is content-type: json
259
+ }
260
+
261
+ // Otherwise, we have JSON in the body
262
+ else {
263
+
264
+ // Sanity check the body
242
265
  if (typeof req.headers['content-type'] !== 'string'
243
266
  || req.headers['content-type'].toLowerCase() !== 'application/json')
244
267
  console.error('Error: PUT content-type is not application/json')
268
+
269
+ // Start downloading it
245
270
  var body = ''
246
271
  req.on('data', chunk => {body += chunk.toString()})
272
+
273
+ // When the body is downloaded...
247
274
  req.on('end', () => {
275
+
276
+ // Parse it as JSON
248
277
  try {
249
- var path = req.url.substr(1)
250
- var obj = from_http_body(path, body)
278
+ var obj = from_http_body(path, key)
251
279
  } catch (e) {
252
280
  console.error('Error: PUT body was not valid json', e)
253
281
  res.statusCode = 500
@@ -255,73 +283,24 @@ function import_server (bus, make_statebus, options)
255
283
  return
256
284
  }
257
285
 
258
- // Make a temporary client bus
259
- var cbus = bus.bus_for_http_client(req, res)
260
- var t = {
261
- version: req.version || cbus.new_version(),
262
- parents: req.parents
263
- }
264
-
265
286
  // If the peer declares itself, let's remember it so that
266
287
  // we don't send it echoes
267
- if (req.headers.peer) {
268
- let peer = req.headers.peer,
269
- key = obj.key
270
- var cb = cbus.http_callbacks && cbus.http_callbacks[
271
- JSON.stringify({peer, key})
272
- ]
273
- if (cb) cb.has_seen(cbus, key, t.version)
274
- }
288
+ var send_func = client_bus.dialogues[req.headers.dialogue]
289
+ if (send_func) send_func.has_seen(client_bus, key, t.version)
275
290
 
276
- // Now send the version to the bus!
277
- cbus.set(obj, t)
291
+ // Now send the update to the bus!
292
+ client_bus.set(obj, t)
278
293
 
279
294
  res.statusCode = 200
280
295
  res.end()
281
- cbus.http_unsubscribe(req)
296
+ client_bus.http_unsubscribe(req)
282
297
  })
283
298
  }
284
299
  }
285
- else
300
+ else {
301
+ console.log('IN: nothing on the bus for it! passing along...')
286
302
  next()
287
- },
288
-
289
- bus_for_http_client: function (req, res) {
290
- var bus = this
291
- if (!bus.bus_for_http_client.counter) {
292
- bus.bus_for_http_client.counter = 0
293
- bus.bus_for_http_client.busses = {}
294
- }
295
-
296
- // If this client has a peer ID, and we've got a bus for that peer,
297
- // then re-use it!
298
- if (req.peer && bus.bus_for_http_client.busses[req.peer]) {
299
- var cbus = bus.bus_for_http_client.busses[req.peer]
300
- cbus.client_ip = req.connection.remoteAddress
301
- cbus.num_subscriptions++
302
- return cbus
303
- }
304
-
305
- // Otherwise, create a new bus
306
- var cbus = make_statebus()
307
- cbus.label = 'client_http' + bus.bus_for_http_client.counter++
308
- cbus.master = bus
309
- cbus.num_subscriptions = 1
310
- cbus.http_unsubscribe = (req) => {
311
- cbus.num_subscriptions--
312
- if (cbus.num_subscriptions === 0) {
313
- // log('Last subscription! Killing client bus!')
314
- cbus.delete_bus()
315
- delete bus.bus_for_http_client.busses[req.peer]
316
- }
317
- }
318
- bus.bus_for_http_client.busses[req.peer] = cbus
319
-
320
- // And log into it as the client
321
- cbus.serves_auth({remoteAddress: req.connection.remoteAddress}, bus)
322
- bus.options.client(cbus)
323
- cbus.set({key: 'current_user', val: {client: req.peer}})
324
- return cbus
303
+ }
325
304
  },
326
305
 
327
306
  make_http_server: function make_http_server (options) {
@@ -417,12 +396,12 @@ function import_server (bus, make_statebus, options)
417
396
  })
418
397
 
419
398
  },
420
- sockjs_server: function sockjs_server(httpserver, client_bus_func) {
421
- var master = this
399
+ sockjs_server: function sockjs_server(httpserver) {
400
+ var master = bus
422
401
  var client_num = 0
423
402
  // var client_busses = {} // XXX work in progress
424
403
  var log = master.log
425
- if (client_bus_func) {
404
+ if (master.custom_clients) {
426
405
  master.set({key: 'connections', val: {}}) // Clean out old sessions
427
406
  var connections = master.get('connections')
428
407
  }
@@ -432,7 +411,7 @@ function import_server (bus, make_statebus, options)
432
411
  heartbeat_delay: 6000 * 1000
433
412
  })
434
413
  s.on('connection', function(conn) {
435
- if (client_bus_func) {
414
+ if (master.custom_clients) {
436
415
  // To do for pooling client busses:
437
416
  // - What do I do with connections? Do they pool at all?
438
417
  // - Before creating a new bus here, check to see if there's
@@ -441,15 +420,18 @@ function import_server (bus, make_statebus, options)
441
420
  // - When disconnecting, decrement the number, and if it gets
442
421
  // to zero, delete the client bus.
443
422
 
444
- connections.val[conn.id] = {client: conn.id, // client is deprecated
445
- id: conn.id}
446
- master.set(connections)
423
+ // connections.val[conn.id] = {id: conn.id}
424
+ // master.set(connections)
425
+
426
+ var client_id = conn.headers.peer ||
427
+ require('cookie').parse(conn.headers.cookie || '').peer
447
428
 
448
429
  var client = make_statebus()
449
430
  client.label = 'client' + client_num++
450
431
  master.label = master.label || 'master'
432
+ client.client_ip = conn.remoteAddress
451
433
  client.master = master
452
- client_bus_func(client, conn)
434
+ master.custom_clients(client, client_id)
453
435
  } else
454
436
  var client = master
455
437
 
@@ -519,16 +501,22 @@ function import_server (bus, make_statebus, options)
519
501
  break
520
502
  case 'set':
521
503
  message.version = message.version || client.new_version()
522
- if (message.patches) {
523
- var o = bus.cache[message.set] || {key: message.set}
524
- try {
525
- message.set = bus.apply_patch(o.val, message.patches[0])
526
- } catch (e) {
527
- console.error('Received bad sockjs message from '
528
- + conn.remoteAddress +': ', message, e)
529
- return
530
- }
531
- }
504
+ // if (message.patches) {
505
+ // var o = client.cache[message.set] || {key: message.set}
506
+ // try {
507
+ // console.log('Applying patch', {
508
+ // key: message.set,
509
+ // patches: message.patches,
510
+ // to: o,
511
+ // bus: bus.label
512
+ // })
513
+ // message.set = client.apply_patch(o.val, message.patches[0])
514
+ // } catch (e) {
515
+ // console.error('Received bad sockjs message from '
516
+ // + conn.remoteAddress +': ', message, e)
517
+ // return
518
+ // }
519
+ // }
532
520
  client.set(message.set,
533
521
  {version: message.version,
534
522
  parents: message.parents,
@@ -553,67 +541,68 @@ function import_server (bus, make_statebus, options)
553
541
  log('sockjs_s: disconnected from', conn.remoteAddress, conn.id, client.id)
554
542
  for (var key in our_gets_in)
555
543
  client.forget(key, sockjs_pubber)
556
- if (client_bus_func) {
557
- delete connections.val[conn.id]; master.set(connections)
558
- master.delete('connection/' + conn.id)
544
+ if (master.custom_clients) {
545
+ // delete connections.val[conn.id]; master.set(connections)
546
+ // master.delete('connection/' + conn.id)
559
547
  client.delete_bus()
560
548
  }
561
549
  })
562
550
 
563
- // Define the /connection* state!
564
- if (client_bus_func && !master.options.__secure) {
565
-
566
- // A connection
567
- client('connection/*').getter = function (key, star) {
568
- var result = bus.clone(master.get(key))
569
- if (master.options.connections.include_users && result.user)
570
- result.user = client.get(result.user.key)
571
- result.id = star
572
- result.client = star // Deprecated. Delete this line in v7.
573
- return result
574
- }
575
- client('connection/*').setter = function (o, star, t) {
576
- // Check permissions before editing
577
- if (star !== conn.id && !master.options.connections.edit_others) {
578
- t.abort()
579
- return
580
- }
581
- o.id = star
582
- o.client = star // Deprecated. Delete this line in v7.
583
- master.set(client.clone(o))
584
- }
551
+ // // Define the /connection* state!
552
+ // if (master.custom_clients && !master.options.__secure) {
553
+
554
+ // // A connection
555
+ // client('connection/*').getter = function (key, star) {
556
+ // var result = bus.clone(master.get(key))
557
+ // if (master.options.connections.include_users && result.user)
558
+ // result.user = client.get(result.user.key)
559
+ // result.id = star
560
+ // result.client = star // Deprecated. Delete this line in v7.
561
+ // return result
562
+ // }
563
+ // client('connection/*').setter = function (o, star, t) {
564
+ // // Check permissions before editing
565
+ // if (star !== conn.id && !master.options.connections.edit_others) {
566
+ // t.abort()
567
+ // return
568
+ // }
569
+ // o.id = star
570
+ // o.client = star // Deprecated. Delete this line in v7.
571
+ // master.set(client.clone(o))
572
+ // }
585
573
 
586
- // Your connection
587
- client('connection').getter = function () {
588
- // subscribe to changes in authentication
589
- client.get('current_user')
574
+ // // Your connection
575
+ // client('connection').getter = function () {
576
+ // // subscribe to changes in authentication
577
+ // client.get('current_user')
590
578
 
591
- var result = client.clone(client.get('connection/' + conn.id))
592
- delete result.key
593
- return result
594
- }
595
- client('connection').setter = function (o) {
596
- o = client.clone(o)
597
- o.key = 'connection/' + conn.id
598
- client.set(o)
599
- }
579
+ // var result = client.clone(client.get('connection/' + conn.id))
580
+ // delete result.key
581
+ // return result
582
+ // }
583
+ // client('connection').setter = function (o) {
584
+ // o = client.clone(o)
585
+ // o.key = 'connection/' + conn.id
586
+ // client.set(o)
587
+ // }
600
588
 
601
- // All connections
602
- client('connections').setter = function noop (t) {t.abort()}
603
- client('connections').getter = function () {
604
- var result = []
605
- var conns = master.get('connections').val
606
- for (var connid in conns)
607
- if (connid !== 'key')
608
- result.push(client.get('connection/' + connid))
589
+ // // All connections
590
+ // client('connections').setter = function noop (t) {t.abort()}
591
+ // client('connections').getter = function () {
592
+ // var result = []
593
+ // var conns = master.get('connections').val
594
+ // for (var connid in conns)
595
+ // if (connid !== 'key')
596
+ // result.push(client.get('connection/' + connid))
609
597
 
610
- return {val: result}
611
- }
612
- }
598
+ // return {val: result}
599
+ // }
600
+ // }
613
601
  })
614
602
 
615
603
  // console.log('websocket listening on', '/' + bus.options.websocket_path)
616
- s.installHandlers(httpserver, {prefix:'/' + bus.options.websocket_path})
604
+ s.installHandlers(httpserver || bus.http,
605
+ {prefix:'/' + bus.options.websocket_path})
617
606
  },
618
607
 
619
608
  make_websocket: function make_websocket (url) {
@@ -1215,7 +1204,6 @@ function import_server (bus, make_statebus, options)
1215
1204
  },
1216
1205
 
1217
1206
  smtp (opts) {
1218
- var bus = this
1219
1207
  // Listen for SMTP messages on port 25
1220
1208
  if (opts.domain) {
1221
1209
  var mailin = require('mailin')
@@ -1699,7 +1687,7 @@ function import_server (bus, make_statebus, options)
1699
1687
  }
1700
1688
  },
1701
1689
 
1702
- serves_auth: function serves_auth (conn, master) {
1690
+ serves_auth: function serves_auth (master) {
1703
1691
  // Right now, we only support accounts at '@username', but in general
1704
1692
  // we could allow the prefix to be configurable. We just have to go
1705
1693
  // through this function and make all the regular expressions (like
@@ -1743,6 +1731,7 @@ function import_server (bus, make_statebus, options)
1743
1731
  var users = master.get('users')
1744
1732
  users.val = users.val || []
1745
1733
  for (var i=0; i<users.val.length; i++) {
1734
+ if (!users.val[i]) console.log('Undefined for', {users, i})
1746
1735
  var u = master.get(users.val[i].link)
1747
1736
  if (!(u.val.login || u.val.name)) {
1748
1737
  console.error('upass: this user has bogus name/login', u.key, u.val.name, u.val.login)
@@ -1758,6 +1747,7 @@ function import_server (bus, make_statebus, options)
1758
1747
  }
1759
1748
  return result
1760
1749
  }
1750
+
1761
1751
  master.auth_initialized = true
1762
1752
  master.get('users/passwords')
1763
1753
 
@@ -1864,10 +1854,10 @@ function import_server (bus, make_statebus, options)
1864
1854
 
1865
1855
  // Current User
1866
1856
  client('current_user').getter = function (k) {
1867
- if (!conn.client)
1857
+ if (!client.client_id)
1868
1858
  return {val: {error: 'no client'}}
1869
1859
 
1870
- var u = (master.get('logged_in_clients').val || {})[conn.client]
1860
+ var u = (master.get('logged_in_clients').val || {})[client.client_id]
1871
1861
  var result = {val: {user: u || null, logged_in: !!u}}
1872
1862
  return result
1873
1863
  }
@@ -1888,14 +1878,12 @@ function import_server (bus, make_statebus, options)
1888
1878
  }
1889
1879
 
1890
1880
  client.log('* saving: current_user!')
1891
- if (val.client && !conn.client) {
1892
- // Set the client
1893
- //
1894
- // Note: Should this code be moved upstream, when creating a
1895
- // client bus?
1896
- conn.client = val.client
1881
+
1882
+ if (val.client && !client.client_id) {
1883
+ // Note: HTTP clients already set client.client_id when
1884
+ // creating the client bus, so this code should only run for
1885
+ // websocket clients..
1897
1886
  client.client_id = val.client
1898
- client.client_ip = conn.remoteAddress
1899
1887
 
1900
1888
  // if (conn.id) {
1901
1889
  // var connections = master.get('connections')
@@ -1933,6 +1921,7 @@ function import_server (bus, make_statebus, options)
1933
1921
 
1934
1922
  client.log('auth said:', user_key)
1935
1923
  if (user_key) {
1924
+ client.log('Success!')
1936
1925
  // Success!
1937
1926
  // Associate this user with this session
1938
1927
  // user.log('Logging the user in!', u)
@@ -1941,7 +1930,7 @@ function import_server (bus, make_statebus, options)
1941
1930
  // var connections = master.get('connections')
1942
1931
 
1943
1932
  clients.val = clients.val || {}
1944
- clients.val[conn.client] = {link: user_key}
1933
+ clients.val[client.client_id] = {link: user_key}
1945
1934
  // connections.val[conn.id].user = {link: user_key}
1946
1935
 
1947
1936
  master.set(clients)
@@ -1961,12 +1950,13 @@ function import_server (bus, make_statebus, options)
1961
1950
  }
1962
1951
 
1963
1952
  else if (val.logout) {
1964
- client.log('current_user: logging out')
1953
+ client.log('current_user: logging out of client ',
1954
+ client.client_id)
1965
1955
  var clients = master.get('logged_in_clients')
1966
1956
  // var connections = master.get('connections')
1967
1957
 
1968
1958
  clients.val = clients.val || {}
1969
- delete clients.val[conn.client]
1959
+ delete clients.val[client.client_id]
1970
1960
  // connections.val[conn.id].user = null
1971
1961
 
1972
1962
  master.set(clients)
@@ -2450,8 +2440,8 @@ function import_server (bus, make_statebus, options)
2450
2440
  path = path || 'client.js'
2451
2441
  bus.http.get('/' + path, (req, res) => {
2452
2442
  var files =
2453
- ['extras/coffee.js', 'extras/sockjs.js',
2454
- 'statebus.js', 'client.js'].map((f) => fs.readFileSync('node_modules/statebus/' + f))
2443
+ ['extras/coffee.js', 'extras/sockjs.js', 'extras/react12.min.js',
2444
+ 'statebus.js', 'client-library.js'].map((f) => fs.readFileSync('node_modules/statebus/' + f))
2455
2445
  files.unshift(fs.readFileSync(
2456
2446
  'node_modules/braid-http/braid-http-client.js'
2457
2447
  ))