|
|
@ -2,42 +2,115 @@ |
|
|
|
|
|
|
|
var Devices = module.exports; |
|
|
|
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); |
|
|
|
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) { |
|
|
|
var devices = store[servername] || []; |
|
|
|
// Check if this domain has an active device
|
|
|
|
var devices = store._domains[servername] || []; |
|
|
|
var index = devices.indexOf(device); |
|
|
|
|
|
|
|
if (index < 0) { |
|
|
|
console.warn('attempted to remove non-present device', device.deviceId, 'from', servername); |
|
|
|
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]; |
|
|
|
}; |
|
|
|
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) { |
|
|
|
if (store[servername] && store[servername].length) { |
|
|
|
return store[servername]; |
|
|
|
// efficient lookup first
|
|
|
|
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
|
|
|
|
// first so the one with the biggest natural match with be found first.
|
|
|
|
var deviceList = []; |
|
|
|
Object.keys(store).filter(function (pattern) { |
|
|
|
return pattern[0] === '*' && store[pattern].length; |
|
|
|
Object.keys(store._domains).filter(function (pattern) { |
|
|
|
return pattern[0] === '*' && store._domains[pattern].length; |
|
|
|
}).sort(function (a, b) { |
|
|
|
return b.length - a.length; |
|
|
|
}).some(function (pattern) { |
|
|
|
var subPiece = pattern.slice(1); |
|
|
|
if (subPiece === servername.slice(-subPiece.length)) { |
|
|
|
console.log('"'+servername+'" matches "'+pattern+'"'); |
|
|
|
deviceList = store[pattern]; |
|
|
|
console.log('[Devices.list] "'+servername+'" matches "'+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 deviceList; |
|
|
|
}; |
|
|
|
/* |
|
|
|
Devices.active = function (store, id) { |
|
|
|
var dev = store._devices[id]; |
|
|
|
return !!dev; |
|
|
|
}; |
|
|
|
*/ |
|
|
|
Devices.exist = function (store, servername) { |
|
|
|
return !!(Devices.list(store, servername).length); |
|
|
|
}; |
|
|
|