forked from coolaj86/goldilocks.js
105 lines
2.7 KiB
JavaScript
105 lines
2.7 KiB
JavaScript
'use strict';
|
|
|
|
var PromiseA = require('bluebird');
|
|
var path = require('path');
|
|
var fs = PromiseA.promisifyAll(require('fs'));
|
|
|
|
module.exports.create = function (deps, conf) {
|
|
var hrIds = require('human-readable-ids').humanReadableIds;
|
|
var scmp = require('scmp');
|
|
var storageDir = path.join(__dirname, '..', 'var');
|
|
|
|
function read(fileName) {
|
|
return fs.readFileAsync(path.join(storageDir, fileName))
|
|
.then(JSON.parse, function (err) {
|
|
if (err.code === 'ENOENT') {
|
|
return {};
|
|
}
|
|
throw err;
|
|
});
|
|
}
|
|
function write(fileName, obj) {
|
|
return fs.mkdirAsync(storageDir).catch(function (err) {
|
|
if (err.code !== 'EEXIST') {
|
|
console.error('failed to mkdir', storageDir, err.toString());
|
|
}
|
|
}).then(function () {
|
|
return fs.writeFileAsync(path.join(storageDir, fileName), JSON.stringify(obj), 'utf8');
|
|
});
|
|
}
|
|
|
|
var owners = {
|
|
_filename: 'owners.json'
|
|
, all: function () {
|
|
return read(this._filename).then(function (owners) {
|
|
return Object.keys(owners).map(function (id) {
|
|
var owner = owners[id];
|
|
owner.id = id;
|
|
return owner;
|
|
});
|
|
});
|
|
}
|
|
, get: function (id) {
|
|
// While we could directly read the owners file and access the id directly from
|
|
// the resulting object I'm not sure of the details of how the object key lookup
|
|
// works or whether that would expose us to timing attacks.
|
|
// See https://codahale.com/a-lesson-in-timing-attacks/
|
|
return this.all().then(function (owners) {
|
|
return owners.filter(function (owner) {
|
|
return scmp(id, owner.id);
|
|
})[0];
|
|
});
|
|
}
|
|
, exists: function (id) {
|
|
return this.get(id).then(function (owner) {
|
|
return !!owner;
|
|
});
|
|
}
|
|
, set: function (id, obj) {
|
|
var self = this;
|
|
return read(self._filename).then(function (owners) {
|
|
obj.id = id;
|
|
owners[id] = obj;
|
|
return write(self._filename, owners);
|
|
});
|
|
}
|
|
};
|
|
|
|
var config = {
|
|
save: function (changes) {
|
|
deps.messenger.send({
|
|
type: 'com.daplie.goldilocks/config'
|
|
, changes: changes
|
|
});
|
|
}
|
|
};
|
|
|
|
var mdnsId = {
|
|
_filename: 'mdns-id'
|
|
, get: function () {
|
|
var self = this;
|
|
return read("mdns-id").then(function (result) {
|
|
if (typeof result !== 'string') {
|
|
throw new Error('mDNS ID not present');
|
|
}
|
|
return result;
|
|
}).catch(function () {
|
|
return self.set(hrIds.random());
|
|
});
|
|
}
|
|
|
|
, set: function (value) {
|
|
var self = this;
|
|
return write(self._filename, value).then(function () {
|
|
return self.get();
|
|
});
|
|
}
|
|
};
|
|
|
|
return {
|
|
owners: owners
|
|
, config: config
|
|
, mdnsId: mdnsId
|
|
};
|
|
};
|