From d586e011e254247a7afef01ab47f352751d6298c Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Tue, 23 Jan 2018 15:21:20 -0700 Subject: [PATCH] WIP update existing records --- lib/httpd.js | 28 +++++++++++++++++++ lib/store.json.js | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/lib/httpd.js b/lib/httpd.js index feb6136..f922391 100644 --- a/lib/httpd.js +++ b/lib/httpd.js @@ -88,6 +88,18 @@ module.exports.create = function (cli, engine/*, dnsd*/) { var app = express(); var httpServer = require('http').createServer(app); + function hasClaim(claim) { + return function (req, res, next) { + if ((req.token.scp||'').split(/[\s,]/g).some(function (c) { + return claim === c; + })) { + next(); + } else { + next(new Error("no claim to '" + claim + "' in token")); + } + }; + } + app.use('/api', function (req, res, next) { var auth = (req.headers.authorization || req.query.token || '').split(/\s+/)[1]; var token; @@ -228,6 +240,22 @@ module.exports.create = function (cli, engine/*, dnsd*/) { }).map(mapRecord) }); }); }); + app.post('/api/records/:id?', hasClaim('+rw@adns.org'), function (req, res) { + console.log('req.body:', req.body); + var record = req.body || {}; + record.id = req.params.id || record.id; + + if ('SOA' === record.type) { + // TODO be strict about what can be edited + engine.records.save(record, function (err, record) { + res.send({ success: true }); + }); + } else { + engine.records.save(record, function (err, record) { + res.send({ success: true }); + }); + } + }); app.use('/', express.static(path.join(__dirname, 'public'))); diff --git a/lib/store.json.js b/lib/store.json.js index c33be47..6f5e03d 100644 --- a/lib/store.json.js +++ b/lib/store.json.js @@ -25,6 +25,29 @@ module.exports.create = function (opts) { record.id = crypto.randomBytes(16).toString('hex'); } }); + db.save = function (cb) { + if (db.save._saving) { + console.log('make pending'); + db.save._pending.push(cb); + return; + } + + db.save._saving = true; + require('fs').writeFile(opts.filepath, JSON.stringify(db, null, 2), function (err) { + console.log('done writing'); + var pending = db.save._pending.splice(0); + db.save._saving = false; + cb(err); + if (!pending.length) { + return; + } + db.save(function (err) { + console.log('double save'); + pending.forEach(function (cb) { cb(err); }); + }); + }); + }; + db.save._pending = []; require('fs').writeFileSync(opts.filepath, JSON.stringify(db, null, 2)); engine.primaryNameservers = db.primaryNameservers; @@ -120,6 +143,52 @@ module.exports.create = function (opts) { cb(null, myRecords); }); } + , save: function (record, cb) { + if (record.id) { + console.log('update record!'); + engine.records.update(record, cb); + } else { + engine.records.create(record, cb); + } + } + , update: function (record, cb) { + var existing; + var dirty; + + db.records.some(function (r) { + if (r.id === record.id) { + existing = r; + return true; + } + }); + + if (!existing) { + console.log('no existing record'); + cb(new Error("record for '" + record.id + "' does not exist"), null); + return; + } + + console.log('found existing record'); + console.log(existing); + console.log(record); + Object.keys(record).forEach(function (key) { + if (existing[key] !== record[key]) { + dirty = true; + console.log(existing[key], record[key]); + existing[key] = record[key]; + } + }); + + record.updatedAt = new Date().toISOString(); // Math.round(Date.now() / 1000); + if (dirty) { + record.changedAt = record.updatedAt; + } + + console.log('saving...'); + db.save(function (err) { + cb(err, !err && existing || null); + }); + } }; return engine;