treat devices more like devices and less like domains
This commit is contained in:
parent
bb018c538d
commit
5380a519bd
|
@ -10,7 +10,7 @@
|
||||||
, "immed": true
|
, "immed": true
|
||||||
, "undef": true
|
, "undef": true
|
||||||
, "unused": true
|
, "unused": true
|
||||||
, "latedef": true
|
, "latedef": "nofunc"
|
||||||
, "curly": true
|
, "curly": true
|
||||||
, "trailing": true
|
, "trailing": true
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,42 +2,115 @@
|
||||||
|
|
||||||
var Devices = module.exports;
|
var Devices = module.exports;
|
||||||
Devices.add = function (store, servername, newDevice) {
|
Devices.add = function (store, servername, newDevice) {
|
||||||
var devices = store[servername] || [];
|
if (!store._devices) { store._devices = {}; }
|
||||||
|
if (!store._domains) { store._domains = {}; }
|
||||||
|
if (!store._domains[servername]) {
|
||||||
|
store._domains[servername] = [];
|
||||||
|
}
|
||||||
|
var devices = store._domains[servername];
|
||||||
devices.push(newDevice);
|
devices.push(newDevice);
|
||||||
store[servername] = devices;
|
|
||||||
|
// TODO only use a device id
|
||||||
|
var devId = newDevice.id || servername;
|
||||||
|
if (!store._devices[devId]) {
|
||||||
|
store._devices[devId] = newDevice;
|
||||||
|
if (!store._devices[devId].domains) {
|
||||||
|
store._devices[devId].domains = {};
|
||||||
|
}
|
||||||
|
if (!store._devices[devId].domains[servername]) {
|
||||||
|
store._devices[devId].domains[servername] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Devices.alias = function (store, servername, alias) {
|
||||||
|
if (!store._domains[servername]) {
|
||||||
|
store._domains[servername] = [];
|
||||||
|
}
|
||||||
|
if (!store._domains[servername]._primary) {
|
||||||
|
store._domains[servername]._primary = servername;
|
||||||
|
}
|
||||||
|
if (!store._domains[servername].aliases) {
|
||||||
|
store._domains[servername].aliases = {};
|
||||||
|
}
|
||||||
|
store._domains[alias] = store._domains[servername];
|
||||||
|
store._domains[servername].aliases[alias] = true;
|
||||||
};
|
};
|
||||||
Devices.remove = function (store, servername, device) {
|
Devices.remove = function (store, servername, device) {
|
||||||
var devices = store[servername] || [];
|
// Check if this domain has an active device
|
||||||
|
var devices = store._domains[servername] || [];
|
||||||
var index = devices.indexOf(device);
|
var index = devices.indexOf(device);
|
||||||
|
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
console.warn('attempted to remove non-present device', device.deviceId, 'from', servername);
|
console.warn('attempted to remove non-present device', device.deviceId, 'from', servername);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unlink this domain from this device
|
||||||
|
var domains = store._devices[devices[index].id || servername].domains;
|
||||||
|
delete domains[servername];
|
||||||
|
/*
|
||||||
|
// remove device if no domains remain
|
||||||
|
// nevermind, a device can hang around in limbo for a bit
|
||||||
|
if (!Object.keys(domains).length) {
|
||||||
|
delete store._devices[devices[index].id || servername];
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// unlink this device from this domain
|
||||||
return devices.splice(index, 1)[0];
|
return devices.splice(index, 1)[0];
|
||||||
};
|
};
|
||||||
|
Devices.close = function (store, device) {
|
||||||
|
var dev = store._devices[device.id];
|
||||||
|
var id = device.id;
|
||||||
|
// because we're actually using names rather than don't have reliable deviceIds yet
|
||||||
|
if (!dev) {
|
||||||
|
Object.keys(store._devices[device.id]).some(function (key) {
|
||||||
|
if (store._devices[key].socketId === device.socketId) {
|
||||||
|
id = key;
|
||||||
|
delete store._devices[key];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO double check that all domains are removed
|
||||||
|
if (id) { delete store._devices[id]; }
|
||||||
|
};
|
||||||
Devices.list = function (store, servername) {
|
Devices.list = function (store, servername) {
|
||||||
if (store[servername] && store[servername].length) {
|
// efficient lookup first
|
||||||
return store[servername];
|
if (store._domains[servername] && store._domains[servername].length) {
|
||||||
|
return store._domains[servername]._primary && store._domains[store._domains[servername]._primary] || store._domains[servername];
|
||||||
}
|
}
|
||||||
// There wasn't an exact match so check any of the wildcard domains, sorted longest
|
// There wasn't an exact match so check any of the wildcard domains, sorted longest
|
||||||
// first so the one with the biggest natural match with be found first.
|
// first so the one with the biggest natural match with be found first.
|
||||||
var deviceList = [];
|
var deviceList = [];
|
||||||
Object.keys(store).filter(function (pattern) {
|
Object.keys(store._domains).filter(function (pattern) {
|
||||||
return pattern[0] === '*' && store[pattern].length;
|
return pattern[0] === '*' && store._domains[pattern].length;
|
||||||
}).sort(function (a, b) {
|
}).sort(function (a, b) {
|
||||||
return b.length - a.length;
|
return b.length - a.length;
|
||||||
}).some(function (pattern) {
|
}).some(function (pattern) {
|
||||||
var subPiece = pattern.slice(1);
|
var subPiece = pattern.slice(1);
|
||||||
if (subPiece === servername.slice(-subPiece.length)) {
|
if (subPiece === servername.slice(-subPiece.length)) {
|
||||||
console.log('"'+servername+'" matches "'+pattern+'"');
|
console.log('[Devices.list] "'+servername+'" matches "'+pattern+'"');
|
||||||
deviceList = store[pattern];
|
deviceList = store._domains[pattern];
|
||||||
|
|
||||||
|
// Devices.alias(store, '*.example.com', 'sub.example.com'
|
||||||
|
// '*.example.com' retrieves a reference to 'example.com'
|
||||||
|
// and this reference then also referenced by 'sub.example.com'
|
||||||
|
// Hence this O(n) check is replaced with the O(1) check above
|
||||||
|
Devices.alias(store, pattern, servername);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return deviceList;
|
return deviceList;
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
|
Devices.active = function (store, id) {
|
||||||
|
var dev = store._devices[id];
|
||||||
|
return !!dev;
|
||||||
|
};
|
||||||
|
*/
|
||||||
Devices.exist = function (store, servername) {
|
Devices.exist = function (store, servername) {
|
||||||
return !!(Devices.list(store, servername).length);
|
return !!(Devices.list(store, servername).length);
|
||||||
};
|
};
|
||||||
|
|
|
@ -211,10 +211,13 @@ var Server = {
|
||||||
function hangup() {
|
function hangup() {
|
||||||
clearTimeout(srv.timeoutId);
|
clearTimeout(srv.timeoutId);
|
||||||
console.log('[ws] device hangup', Server.logName(state, srv), 'connection closing');
|
console.log('[ws] device hangup', Server.logName(state, srv), 'connection closing');
|
||||||
|
// remove the allowed domains from the list (but leave the socket)
|
||||||
Object.keys(srv.grants).forEach(function (jwtoken) {
|
Object.keys(srv.grants).forEach(function (jwtoken) {
|
||||||
Server.removeToken(state, srv, jwtoken);
|
Server.removeToken(state, srv, jwtoken);
|
||||||
});
|
});
|
||||||
srv.ws.terminate();
|
srv.ws.terminate();
|
||||||
|
// remove the socket from the list, period
|
||||||
|
Devices.close(state.deviceLists, srv);
|
||||||
}
|
}
|
||||||
|
|
||||||
srv.lastActivity = Date.now();
|
srv.lastActivity = Date.now();
|
||||||
|
@ -550,7 +553,7 @@ var Server = {
|
||||||
|
|
||||||
module.exports.store = { Devices: Devices };
|
module.exports.store = { Devices: Devices };
|
||||||
module.exports.create = function (state) {
|
module.exports.create = function (state) {
|
||||||
state.deviceLists = {};
|
state.deviceLists = { _domains: {}, _devices: {} };
|
||||||
state.deviceCallbacks = {};
|
state.deviceCallbacks = {};
|
||||||
state.srvs = {};
|
state.srvs = {};
|
||||||
|
|
||||||
|
@ -577,6 +580,8 @@ module.exports.create = function (state) {
|
||||||
var initToken;
|
var initToken;
|
||||||
srv.ws = _ws;
|
srv.ws = _ws;
|
||||||
srv.upgradeReq = _upgradeReq;
|
srv.upgradeReq = _upgradeReq;
|
||||||
|
// TODO use device's ECDSA thumbprint as device id
|
||||||
|
srv.id = null;
|
||||||
srv.socketId = Packer.socketToId(srv.upgradeReq.socket);
|
srv.socketId = Packer.socketToId(srv.upgradeReq.socket);
|
||||||
srv.grants = {};
|
srv.grants = {};
|
||||||
srv.clients = {};
|
srv.clients = {};
|
||||||
|
|
Loading…
Reference in New Issue