move account db to own file
This commit is contained in:
parent
f54c4dde7a
commit
b60658ee81
|
@ -0,0 +1,235 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var PromiseA;
|
||||||
|
try {
|
||||||
|
PromiseA = require('bluebird');
|
||||||
|
} catch(e) {
|
||||||
|
PromiseA = global.Promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = require('path');
|
||||||
|
var sfs = require('safe-replace');
|
||||||
|
|
||||||
|
var DB = module.exports = {};
|
||||||
|
DB._savefile = path.join(__dirname, 'permissions.json');
|
||||||
|
DB._load = function () {
|
||||||
|
try {
|
||||||
|
DB._perms = require(DB._savefile);
|
||||||
|
} catch(e) {
|
||||||
|
try {
|
||||||
|
DB._perms = require(DB._savefile + '.bak');
|
||||||
|
} catch(e) {
|
||||||
|
DB._perms = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DB._byDomain = {};
|
||||||
|
DB._byPort = {};
|
||||||
|
DB._byEmail = {};
|
||||||
|
DB._byPpid = {};
|
||||||
|
DB._byId = {};
|
||||||
|
DB._grants = {};
|
||||||
|
DB._grantsMap = {};
|
||||||
|
DB._perms.forEach(function (acc) {
|
||||||
|
if (acc.id) {
|
||||||
|
// if account has an id
|
||||||
|
DB._byId[acc.id] = acc;
|
||||||
|
if (!DB._grants[acc.id]) {
|
||||||
|
DB._grantsMap[acc.id] = {};
|
||||||
|
DB._grants[acc.id] = [];
|
||||||
|
}
|
||||||
|
acc.domains.forEach(function (d) {
|
||||||
|
DB._grants[d.name + '|id|' + acc.id] = true;
|
||||||
|
if (!DB._grantsMap[acc.id][d.name]) {
|
||||||
|
DB._grantsMap[acc.id][d.name] = d;
|
||||||
|
DB._grants[acc.id].push(d);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
acc.ports.forEach(function (p) {
|
||||||
|
DB._grants[p.number + '|id|' + acc.id] = true;
|
||||||
|
if (!DB._grantsMap[acc.id][p.number]) {
|
||||||
|
DB._grantsMap[acc.id][p.number] = p;
|
||||||
|
DB._grants[acc.id].push(p);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (acc.nodes[0] && 'email' === acc.nodes[0].type) {
|
||||||
|
// if primary (first) node is email
|
||||||
|
//console.log("XXXX email", acc.nodes[0].name);
|
||||||
|
if (!DB._byEmail[acc.nodes[0].name]) {
|
||||||
|
DB._byEmail[acc.nodes[0].name] = {
|
||||||
|
account: acc
|
||||||
|
, node: acc.nodes[0]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// map domains to all nodes that have permission
|
||||||
|
// (which permission could be granted by more than one account)
|
||||||
|
acc.nodes.forEach(function (node) {
|
||||||
|
if ('mailto' === node.scheme || 'email' === node.type) {
|
||||||
|
if (!DB._grants[node.name]) {
|
||||||
|
DB._grantsMap[node.name] = {};
|
||||||
|
DB._grants[node.name] = [];
|
||||||
|
}
|
||||||
|
acc.domains.forEach(function (d) {
|
||||||
|
DB._grants[d.name + '|' + (node.scheme||node.type) + '|' + node.name] = true;
|
||||||
|
if (!DB._grantsMap[node.name][d.name]) {
|
||||||
|
DB._grantsMap[node.name][d.name] = d;
|
||||||
|
DB._grants[node.name].push(d);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
acc.ports.forEach(function (p) {
|
||||||
|
DB._grants[p.number + '|' + (node.scheme||node.type) + '|' + node.name] = true;
|
||||||
|
if (!DB._grantsMap[node.name][p.number]) {
|
||||||
|
DB._grantsMap[node.name][p.number] = p;
|
||||||
|
DB._grants[node.name].push(p);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// TODO this also should be maps/arrays (... or just normal database)
|
||||||
|
acc.domains.forEach(function (domain) {
|
||||||
|
if (DB._byDomain[domain.name]) {
|
||||||
|
console.warn("duplicate domain '" + domain.name + "'");
|
||||||
|
console.warn("::existing account '" + acc.nodes.map(function (node) { return node.name; }) + "'");
|
||||||
|
console.warn("::new account '" + DB._byDomain[domain.name].account.nodes.map(function (node) { return node.name; }) + "'");
|
||||||
|
}
|
||||||
|
DB._byDomain[domain.name] = {
|
||||||
|
account: acc
|
||||||
|
, domain: domain
|
||||||
|
};
|
||||||
|
});
|
||||||
|
acc.ports.forEach(function (port) {
|
||||||
|
if (DB._byPort[port.number]) {
|
||||||
|
console.warn("duplicate port '" + port.number + "'");
|
||||||
|
console.warn("::existing account '" + acc.nodes.map(function (node) { return node.name; }) + "'");
|
||||||
|
console.warn("::new account '" + DB._byPort[port.number].account.nodes.map(function (node) { return node.name; }) + "'");
|
||||||
|
}
|
||||||
|
DB._byPort[port.number] = {
|
||||||
|
account: acc
|
||||||
|
, port: port
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
DB._load();
|
||||||
|
DB.accounts = {};
|
||||||
|
DB.accounts.get = function (obj) {
|
||||||
|
return PromiseA.resolve().then(function () {
|
||||||
|
//console.log('XXXX obj.name', DB._byEmail[obj.name]);
|
||||||
|
return DB._byId[obj.name] || (DB._byEmail[obj.name] || {}).account || null;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
DB.accounts.add = function (obj) {
|
||||||
|
return PromiseA.resolve().then(function () {
|
||||||
|
if (obj.id) {
|
||||||
|
// TODO more checks
|
||||||
|
DB._perms.push(obj);
|
||||||
|
} else if ('email' === obj.nodes[0].type || obj.email) {
|
||||||
|
obj.email = undefined;
|
||||||
|
DB._perms.push(obj);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
DB.domains = {};
|
||||||
|
DB.domains.available = function (name) {
|
||||||
|
return PromiseA.resolve().then(function () {
|
||||||
|
return !DB._byDomain[name];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
DB.domains._add = function (acc, opts) {
|
||||||
|
// TODO verifications to change ownership of a domain
|
||||||
|
return PromiseA.resolve().then(function () {
|
||||||
|
var err;
|
||||||
|
//var acc = DB._byId[aid];
|
||||||
|
var domain = {
|
||||||
|
name: (opts.domain || opts.name)
|
||||||
|
, hostname: opts.hostname
|
||||||
|
, os: opts.os
|
||||||
|
, createdAt: new Date().toISOString()
|
||||||
|
, wildcard: opts.wildcard
|
||||||
|
};
|
||||||
|
var pdomain;
|
||||||
|
var parts = (opts.domain || domain.name).split('.').map(function (el, i, arr) {
|
||||||
|
return arr.slice(i).join('.');
|
||||||
|
}).reverse();
|
||||||
|
parts.shift();
|
||||||
|
parts.pop();
|
||||||
|
if (parts.some(function (part) {
|
||||||
|
if (DB._byDomain[part]) {
|
||||||
|
pdomain = part;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
})) {
|
||||||
|
err = new Error("'" + domain.name + "' exists as '" + pdomain + "' and therefore requires an admin to review and approve");
|
||||||
|
err.code = "E_REQ_ADMIN";
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
if (DB._byDomain[domain.name]) {
|
||||||
|
if (acc !== DB._byDomain[domain.name].account) {
|
||||||
|
throw new Error("domain '" + domain.name + "' exists");
|
||||||
|
}
|
||||||
|
// happily ignore non-change
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DB._byDomain[domain.name] = {
|
||||||
|
account: acc
|
||||||
|
, domain: domain
|
||||||
|
};
|
||||||
|
acc.domains.push(domain);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
DB.ports = {};
|
||||||
|
DB.ports.available = function (number) {
|
||||||
|
return PromiseA.resolve().then(function () {
|
||||||
|
return !DB._byPort[number];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
DB.ports._add = function (acc, opts) {
|
||||||
|
return PromiseA.resolve().then(function () {
|
||||||
|
//var acc = DB._byId[aid];
|
||||||
|
var port = {
|
||||||
|
number: opts.port || opts.number
|
||||||
|
, hostname: opts.hostname
|
||||||
|
, os: opts.os
|
||||||
|
, createdAt: new Date().toISOString()
|
||||||
|
};
|
||||||
|
if (DB._byPort[port.number]) {
|
||||||
|
// TODO verifications
|
||||||
|
throw new Error("port '" + port.number + "' exists");
|
||||||
|
}
|
||||||
|
DB._byPort[port.number] = {
|
||||||
|
account: acc
|
||||||
|
, port: port
|
||||||
|
};
|
||||||
|
acc.ports.push(port);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
DB._save = function () {
|
||||||
|
return sfs.writeFileAsync(DB._savefile, JSON.stringify(DB._perms));
|
||||||
|
};
|
||||||
|
DB._saveToken = null;
|
||||||
|
DB._savePromises = [];
|
||||||
|
DB._savePromise = PromiseA.resolve();
|
||||||
|
DB.save = function () {
|
||||||
|
clearTimeout(DB._saveToken);
|
||||||
|
return new PromiseA(function (resolve, reject) {
|
||||||
|
function doSave() {
|
||||||
|
DB._savePromise = DB._savePromise.then(function () {
|
||||||
|
return DB._save().then(function (yep) {
|
||||||
|
DB._savePromises.forEach(function (p) {
|
||||||
|
p.resolve(yep);
|
||||||
|
});
|
||||||
|
DB._savePromises.length = 1;
|
||||||
|
}, function (err) {
|
||||||
|
DB._savePromises.forEach(function (p) {
|
||||||
|
p.reject(err);
|
||||||
|
});
|
||||||
|
DB._savePromises.length = 1;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return DB._savePromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
DB._saveToken = setTimeout(doSave, 2500);
|
||||||
|
DB._savePromises.push({ resolve: resolve, reject: reject });
|
||||||
|
});
|
||||||
|
};
|
|
@ -18,229 +18,7 @@ var requestAsync = util.promisify(require('@coolaj86/urequest'));
|
||||||
//var readFileAsync = util.promisify(fs.readFile);
|
//var readFileAsync = util.promisify(fs.readFile);
|
||||||
var mkdirpAsync = util.promisify(require('mkdirp'));
|
var mkdirpAsync = util.promisify(require('mkdirp'));
|
||||||
var TRUSTED_ISSUERS = [ 'oauth3.org' ];
|
var TRUSTED_ISSUERS = [ 'oauth3.org' ];
|
||||||
var DB = {};
|
var DB = require('./db.js');
|
||||||
DB._savefile = path.join(__dirname, 'permissions.json');
|
|
||||||
DB._load = function () {
|
|
||||||
try {
|
|
||||||
DB._perms = require(DB._savefile);
|
|
||||||
} catch(e) {
|
|
||||||
try {
|
|
||||||
DB._perms = require(DB._savefile + '.bak');
|
|
||||||
} catch(e) {
|
|
||||||
DB._perms = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DB._byDomain = {};
|
|
||||||
DB._byPort = {};
|
|
||||||
DB._byEmail = {};
|
|
||||||
DB._byPpid = {};
|
|
||||||
DB._byId = {};
|
|
||||||
DB._grants = {};
|
|
||||||
DB._grantsMap = {};
|
|
||||||
DB._perms.forEach(function (acc) {
|
|
||||||
if (acc.id) {
|
|
||||||
// if account has an id
|
|
||||||
DB._byId[acc.id] = acc;
|
|
||||||
if (!DB._grants[acc.id]) {
|
|
||||||
DB._grantsMap[acc.id] = {};
|
|
||||||
DB._grants[acc.id] = [];
|
|
||||||
}
|
|
||||||
acc.domains.forEach(function (d) {
|
|
||||||
DB._grants[d.name + '|id|' + acc.id] = true;
|
|
||||||
if (!DB._grantsMap[acc.id][d.name]) {
|
|
||||||
DB._grantsMap[acc.id][d.name] = d;
|
|
||||||
DB._grants[acc.id].push(d);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
acc.ports.forEach(function (p) {
|
|
||||||
DB._grants[p.number + '|id|' + acc.id] = true;
|
|
||||||
if (!DB._grantsMap[acc.id][p.number]) {
|
|
||||||
DB._grantsMap[acc.id][p.number] = p;
|
|
||||||
DB._grants[acc.id].push(p);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (acc.nodes[0] && 'email' === acc.nodes[0].type) {
|
|
||||||
// if primary (first) node is email
|
|
||||||
//console.log("XXXX email", acc.nodes[0].name);
|
|
||||||
if (!DB._byEmail[acc.nodes[0].name]) {
|
|
||||||
DB._byEmail[acc.nodes[0].name] = {
|
|
||||||
account: acc
|
|
||||||
, node: acc.nodes[0]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// map domains to all nodes that have permission
|
|
||||||
// (which permission could be granted by more than one account)
|
|
||||||
acc.nodes.forEach(function (node) {
|
|
||||||
if ('mailto' === node.scheme || 'email' === node.type) {
|
|
||||||
if (!DB._grants[node.name]) {
|
|
||||||
DB._grantsMap[node.name] = {};
|
|
||||||
DB._grants[node.name] = [];
|
|
||||||
}
|
|
||||||
acc.domains.forEach(function (d) {
|
|
||||||
DB._grants[d.name + '|' + (node.scheme||node.type) + '|' + node.name] = true;
|
|
||||||
if (!DB._grantsMap[node.name][d.name]) {
|
|
||||||
DB._grantsMap[node.name][d.name] = d;
|
|
||||||
DB._grants[node.name].push(d);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
acc.ports.forEach(function (p) {
|
|
||||||
DB._grants[p.number + '|' + (node.scheme||node.type) + '|' + node.name] = true;
|
|
||||||
if (!DB._grantsMap[node.name][p.number]) {
|
|
||||||
DB._grantsMap[node.name][p.number] = p;
|
|
||||||
DB._grants[node.name].push(p);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// TODO this also should be maps/arrays (... or just normal database)
|
|
||||||
acc.domains.forEach(function (domain) {
|
|
||||||
if (DB._byDomain[domain.name]) {
|
|
||||||
console.warn("duplicate domain '" + domain.name + "'");
|
|
||||||
console.warn("::existing account '" + acc.nodes.map(function (node) { return node.name; }) + "'");
|
|
||||||
console.warn("::new account '" + DB._byDomain[domain.name].account.nodes.map(function (node) { return node.name; }) + "'");
|
|
||||||
}
|
|
||||||
DB._byDomain[domain.name] = {
|
|
||||||
account: acc
|
|
||||||
, domain: domain
|
|
||||||
};
|
|
||||||
});
|
|
||||||
acc.ports.forEach(function (port) {
|
|
||||||
if (DB._byPort[port.number]) {
|
|
||||||
console.warn("duplicate port '" + port.number + "'");
|
|
||||||
console.warn("::existing account '" + acc.nodes.map(function (node) { return node.name; }) + "'");
|
|
||||||
console.warn("::new account '" + DB._byPort[port.number].account.nodes.map(function (node) { return node.name; }) + "'");
|
|
||||||
}
|
|
||||||
DB._byPort[port.number] = {
|
|
||||||
account: acc
|
|
||||||
, port: port
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
DB._load();
|
|
||||||
DB.accounts = {};
|
|
||||||
DB.accounts.get = function (obj) {
|
|
||||||
return PromiseA.resolve().then(function () {
|
|
||||||
//console.log('XXXX obj.name', DB._byEmail[obj.name]);
|
|
||||||
return DB._byId[obj.name] || (DB._byEmail[obj.name] || {}).account || null;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
DB.accounts.add = function (obj) {
|
|
||||||
return PromiseA.resolve().then(function () {
|
|
||||||
if (obj.id) {
|
|
||||||
// TODO more checks
|
|
||||||
DB._perms.push(obj);
|
|
||||||
} else if ('email' === obj.nodes[0].type || obj.email) {
|
|
||||||
obj.email = undefined;
|
|
||||||
DB._perms.push(obj);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
DB.domains = {};
|
|
||||||
DB.domains.available = function (name) {
|
|
||||||
return PromiseA.resolve().then(function () {
|
|
||||||
return !DB._byDomain[name];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
DB.domains._add = function (acc, opts) {
|
|
||||||
// TODO verifications to change ownership of a domain
|
|
||||||
return PromiseA.resolve().then(function () {
|
|
||||||
var err;
|
|
||||||
//var acc = DB._byId[aid];
|
|
||||||
var domain = {
|
|
||||||
name: (opts.domain || opts.name)
|
|
||||||
, hostname: opts.hostname
|
|
||||||
, os: opts.os
|
|
||||||
, createdAt: new Date().toISOString()
|
|
||||||
, wildcard: opts.wildcard
|
|
||||||
};
|
|
||||||
var pdomain;
|
|
||||||
var parts = (opts.domain || domain.name).split('.').map(function (el, i, arr) {
|
|
||||||
return arr.slice(i).join('.');
|
|
||||||
}).reverse();
|
|
||||||
parts.shift();
|
|
||||||
parts.pop();
|
|
||||||
if (parts.some(function (part) {
|
|
||||||
if (DB._byDomain[part]) {
|
|
||||||
pdomain = part;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
})) {
|
|
||||||
err = new Error("'" + domain.name + "' exists as '" + pdomain + "' and therefore requires an admin to review and approve");
|
|
||||||
err.code = "E_REQ_ADMIN";
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
if (DB._byDomain[domain.name]) {
|
|
||||||
if (acc !== DB._byDomain[domain.name].account) {
|
|
||||||
throw new Error("domain '" + domain.name + "' exists");
|
|
||||||
}
|
|
||||||
// happily ignore non-change
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DB._byDomain[domain.name] = {
|
|
||||||
account: acc
|
|
||||||
, domain: domain
|
|
||||||
};
|
|
||||||
acc.domains.push(domain);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
DB.ports = {};
|
|
||||||
DB.ports.available = function (number) {
|
|
||||||
return PromiseA.resolve().then(function () {
|
|
||||||
return !DB._byPort[number];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
DB.ports._add = function (acc, opts) {
|
|
||||||
return PromiseA.resolve().then(function () {
|
|
||||||
//var acc = DB._byId[aid];
|
|
||||||
var port = {
|
|
||||||
number: opts.port || opts.number
|
|
||||||
, hostname: opts.hostname
|
|
||||||
, os: opts.os
|
|
||||||
, createdAt: new Date().toISOString()
|
|
||||||
};
|
|
||||||
if (DB._byPort[port.number]) {
|
|
||||||
// TODO verifications
|
|
||||||
throw new Error("port '" + port.number + "' exists");
|
|
||||||
}
|
|
||||||
DB._byPort[port.number] = {
|
|
||||||
account: acc
|
|
||||||
, port: port
|
|
||||||
};
|
|
||||||
acc.ports.push(port);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
DB._save = function () {
|
|
||||||
return sfs.writeFileAsync(DB._savefile, JSON.stringify(DB._perms));
|
|
||||||
};
|
|
||||||
DB._saveToken = null;
|
|
||||||
DB._savePromises = [];
|
|
||||||
DB._savePromise = PromiseA.resolve();
|
|
||||||
DB.save = function () {
|
|
||||||
clearTimeout(DB._saveToken);
|
|
||||||
return new PromiseA(function (resolve, reject) {
|
|
||||||
function doSave() {
|
|
||||||
DB._savePromise = DB._savePromise.then(function () {
|
|
||||||
return DB._save().then(function (yep) {
|
|
||||||
DB._savePromises.forEach(function (p) {
|
|
||||||
p.resolve(yep);
|
|
||||||
});
|
|
||||||
DB._savePromises.length = 1;
|
|
||||||
}, function (err) {
|
|
||||||
DB._savePromises.forEach(function (p) {
|
|
||||||
p.reject(err);
|
|
||||||
});
|
|
||||||
DB._savePromises.length = 1;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return DB._savePromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
DB._saveToken = setTimeout(doSave, 2500);
|
|
||||||
DB._savePromises.push({ resolve: resolve, reject: reject });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var _auths = module.exports._auths = {};
|
var _auths = module.exports._auths = {};
|
||||||
var Auths = {};
|
var Auths = {};
|
||||||
|
|
Loading…
Reference in New Issue