| 
									
										
										
										
											2017-11-05 09:16:27 -07:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports.create = function (opts) { | 
					
						
							|  |  |  |   // opts = { filepath };
 | 
					
						
							|  |  |  |   var engine = { db: null }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-29 14:54:03 -07:00
										 |  |  |   function notDeleted(r) { | 
					
						
							|  |  |  |     return !r.revokedAt && !r.deletedAt; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 09:16:27 -07:00
										 |  |  |   var db = require(opts.filepath); | 
					
						
							| 
									
										
										
										
											2018-01-26 01:42:24 -07:00
										 |  |  |   var stat = require('fs').statSync(opts.filepath); | 
					
						
							| 
									
										
										
										
											2018-01-21 01:47:37 -07:00
										 |  |  |   var crypto = require('crypto'); | 
					
						
							| 
									
										
										
										
											2018-01-29 15:17:55 -07:00
										 |  |  |   //
 | 
					
						
							|  |  |  |   // Manual Migration
 | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  |   db.primaryNameservers.forEach(function (ns, i, arr) { | 
					
						
							|  |  |  |     if ('string' === typeof ns) { | 
					
						
							| 
									
										
										
										
											2018-01-29 15:54:56 -07:00
										 |  |  |       ns = { name: ns }; | 
					
						
							|  |  |  |       arr[i] = ns; | 
					
						
							| 
									
										
										
										
											2018-01-29 15:17:55 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-21 01:47:37 -07:00
										 |  |  |     if (!ns.id) { | 
					
						
							|  |  |  |       ns.id = crypto.randomBytes(16).toString('hex'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-01-29 15:17:55 -07:00
										 |  |  |   db.zones = db.zones || []; | 
					
						
							|  |  |  |   if (db.domains) { | 
					
						
							|  |  |  |     db.zones = db.zones.concat(db.domains); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-01-21 01:47:37 -07:00
										 |  |  |   db.zones.forEach(function (zone) { | 
					
						
							|  |  |  |     if (!zone.name) { | 
					
						
							|  |  |  |       zone.name = zone.id; | 
					
						
							|  |  |  |       zone.id = null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!zone.id) { | 
					
						
							|  |  |  |       zone.id = crypto.randomBytes(16).toString('hex'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-26 01:42:24 -07:00
										 |  |  |     if (!zone.createdAt) { zone.createdAt = stat.mtime.valueOf(); } | 
					
						
							|  |  |  |     if (!zone.updatedAt) { zone.updatedAt = stat.mtime.valueOf(); } | 
					
						
							| 
									
										
										
										
											2018-01-21 01:47:37 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  |   db.records.forEach(function (record) { | 
					
						
							|  |  |  |     if (!record.id) { | 
					
						
							|  |  |  |       record.id = crypto.randomBytes(16).toString('hex'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-01-29 15:17:55 -07:00
										 |  |  |   require('fs').writeFileSync(opts.filepath, JSON.stringify(db, null, 2)); | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  |   // End Migration
 | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-23 15:21:20 -07:00
										 |  |  |   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 = []; | 
					
						
							| 
									
										
										
										
											2017-11-05 09:16:27 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   engine.primaryNameservers = db.primaryNameservers; | 
					
						
							| 
									
										
										
										
											2018-01-17 01:03:05 -07:00
										 |  |  |   engine.zoneToSoa = function (domain) { | 
					
						
							| 
									
										
										
										
											2018-01-21 01:47:37 -07:00
										 |  |  |     var nameservers = domain.vanityNs || engine.primaryNameservers.map(function (n) { return n.name; }); | 
					
						
							| 
									
										
										
										
											2018-01-17 01:03:05 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     var index = Math.floor(Math.random() * nameservers.length) % nameservers.length; | 
					
						
							|  |  |  |     var nameserver = nameservers[index]; | 
					
						
							|  |  |  |     return { | 
					
						
							| 
									
										
										
										
											2018-01-26 01:42:24 -07:00
										 |  |  |       id: domain.id | 
					
						
							|  |  |  |     , name: domain.name | 
					
						
							| 
									
										
										
										
											2018-01-17 01:03:05 -07:00
										 |  |  |     , typeName: 'SOA' | 
					
						
							|  |  |  |     , className: 'IN' | 
					
						
							|  |  |  |     , ttl: domain.ttl || 60 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // nameserver -- select an NS at random if they're all in sync
 | 
					
						
							|  |  |  |     , primary: nameserver | 
					
						
							|  |  |  |     , name_server: nameserver | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // admin -- email address or domain for admin
 | 
					
						
							| 
									
										
										
										
											2018-01-21 01:47:37 -07:00
										 |  |  |     , admin: domain.admin || ('admin.' + domain.name) | 
					
						
							|  |  |  |     , email_addr: domain.admin || ('admin.' + domain.name) | 
					
						
							| 
									
										
										
										
											2018-01-17 01:03:05 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       // serial -- the version, for cache-busting of secondary nameservers. suggested format: YYYYMMDDnn
 | 
					
						
							|  |  |  |     , serial: domain.serial || Math.round((domain.updatedAt || domain.createdAt || 0) / 1000) | 
					
						
							|  |  |  |     , sn: domain.serial || Math.round((domain.updatedAt || domain.createdAt || 0) / 1000) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // refresh -- only used when nameservers following the DNS NOTIFY spec talk
 | 
					
						
							|  |  |  |     , refresh: domain.refresh || 1800 | 
					
						
							|  |  |  |     , ref: domain.refresh || 1800 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // retry -- only used when nameservers following the DNS NOTIFY spec talk
 | 
					
						
							|  |  |  |     , retry: domain.retry || 600 | 
					
						
							|  |  |  |     , ret: domain.retry || 600 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // expiration -- how long other nameservers should continue when the primary goes down
 | 
					
						
							|  |  |  |     , expiration: domain.expiration || 2419200 | 
					
						
							|  |  |  |     , ex: domain.expiration || 2419200 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // minimum -- how long to cache a non-existent domain (also the default ttl for BIND)
 | 
					
						
							|  |  |  |     , minimum: domain.minimum || 5 | 
					
						
							|  |  |  |     , nx: domain.minimum || 5 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2018-01-10 14:54:08 -07:00
										 |  |  |   engine.peers = { | 
					
						
							|  |  |  |     all: function (cb) { | 
					
						
							| 
									
										
										
										
											2018-01-30 12:03:25 -07:00
										 |  |  |       var dns = require('dns'); | 
					
						
							|  |  |  |       var count = db.primaryNameservers.length; | 
					
						
							|  |  |  |       function gotRecord() { | 
					
						
							|  |  |  |         count -= 1; | 
					
						
							|  |  |  |         if (!count) { | 
					
						
							|  |  |  |           cb(null, db.primaryNameservers); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       function getRecord(ns) { | 
					
						
							|  |  |  |         dns.resolve4(ns.name, function (err, addresses) { | 
					
						
							|  |  |  |           console.log('ns addresses:'); | 
					
						
							|  |  |  |           console.log(addresses); | 
					
						
							|  |  |  |           if (err) { console.error(err); gotRecord(); return; } | 
					
						
							|  |  |  |           ns.type = 'A'; | 
					
						
							|  |  |  |           ns.address = addresses[0]; | 
					
						
							|  |  |  |           gotRecord(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       db.primaryNameservers.forEach(getRecord); | 
					
						
							| 
									
										
										
										
											2018-01-10 14:54:08 -07:00
										 |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2018-01-10 08:14:05 +00:00
										 |  |  |   engine.zones = { | 
					
						
							| 
									
										
										
										
											2018-01-10 01:25:56 -07:00
										 |  |  |     all: function (cb) { | 
					
						
							| 
									
										
										
										
											2018-01-10 08:14:05 +00:00
										 |  |  |       process.nextTick(function () { | 
					
						
							| 
									
										
										
										
											2018-01-29 14:54:03 -07:00
										 |  |  |         cb(null, db.zones.slice(0).filter(notDeleted)); | 
					
						
							| 
									
										
										
										
											2018-01-10 08:14:05 +00:00
										 |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-17 17:01:44 -07:00
										 |  |  |   , get: function (queries, cb) { | 
					
						
							|  |  |  |       if (!Array.isArray(queries)) { | 
					
						
							|  |  |  |         queries = queries.names.map(function (n) { | 
					
						
							|  |  |  |           return { name: n }; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-01-21 01:47:37 -07:00
										 |  |  |       var myDomains = db.zones.filter(function (d) { | 
					
						
							| 
									
										
										
										
											2018-01-17 17:01:44 -07:00
										 |  |  |         return queries.some(function (q) { | 
					
						
							| 
									
										
										
										
											2018-01-29 14:54:03 -07:00
										 |  |  |           return (d.name.toLowerCase() === q.name) && notDeleted(d); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:01:44 -07:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2018-01-10 08:14:05 +00:00
										 |  |  |       }); | 
					
						
							|  |  |  |       process.nextTick(function () { | 
					
						
							|  |  |  |         cb(null, myDomains); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-26 01:42:24 -07:00
										 |  |  |   , touch: function (zone, cb) { | 
					
						
							|  |  |  |       var existing; | 
					
						
							|  |  |  |       db.zones.some(function (z) { | 
					
						
							|  |  |  |         if (z.id && zone.id === z.id) { existing = z; return true; } | 
					
						
							|  |  |  |         if (z.name && zone.name === z.name) { existing = z; return true; } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       if (!existing) { | 
					
						
							|  |  |  |         cb(null, null); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       existing.updatedAt = new Date().valueOf(); // toISOString();
 | 
					
						
							|  |  |  |       console.log('touch saving...'); | 
					
						
							|  |  |  |       db.save(function (err) { | 
					
						
							|  |  |  |         cb(err, !err && existing || null); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , save: function (zone, cb) { | 
					
						
							|  |  |  |       if (zone.id) { | 
					
						
							|  |  |  |         console.log('update zone!'); | 
					
						
							|  |  |  |         engine.zones.update(zone, cb); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         engine.zones.create(zone, cb); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , update: function (zone, cb) { | 
					
						
							|  |  |  |       var existing; | 
					
						
							|  |  |  |       var dirty; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       db.zones.some(function (z) { | 
					
						
							|  |  |  |         if (z.id === zone.id) { | 
					
						
							|  |  |  |           existing = z; | 
					
						
							|  |  |  |           return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!existing) { | 
					
						
							|  |  |  |         console.log('no existing zone'); | 
					
						
							|  |  |  |         cb(new Error("zone for '" + zone.id + "' does not exist"), null); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       console.log('found existing zone'); | 
					
						
							|  |  |  |       console.log(existing); | 
					
						
							|  |  |  |       console.log(zone); | 
					
						
							|  |  |  |       Object.keys(zone).forEach(function (key) { | 
					
						
							|  |  |  |         var keys = [ 'name', 'id', 'revokedAt', 'changedAt', 'insertedAt', 'updatedAt', 'deletedAt' ]; | 
					
						
							|  |  |  |         if (-1 !== keys.indexOf(key)) { return; } | 
					
						
							|  |  |  |         if (existing[key] !== zone[key]) { | 
					
						
							|  |  |  |           dirty = true; | 
					
						
							|  |  |  |           console.log('existing key', key, existing[key], zone[key]); | 
					
						
							|  |  |  |           existing[key] = zone[key]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       zone.updatedAt = new Date().valueOf(); // toISOString(); // Math.round(Date.now() / 1000);
 | 
					
						
							|  |  |  |       if (dirty) { | 
					
						
							|  |  |  |         zone.changedAt = zone.updatedAt; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       console.log('saving...'); | 
					
						
							|  |  |  |       db.save(function (err) { | 
					
						
							|  |  |  |         cb(err, !err && existing || null); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-11-05 09:16:27 -07:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2018-01-10 08:14:05 +00:00
										 |  |  |   engine.records = { | 
					
						
							| 
									
										
										
										
											2018-01-10 01:25:56 -07:00
										 |  |  |     all: function (cb) { | 
					
						
							| 
									
										
										
										
											2018-01-10 08:14:05 +00:00
										 |  |  |       process.nextTick(function () { | 
					
						
							| 
									
										
										
										
											2018-01-29 14:54:03 -07:00
										 |  |  |         cb(null, db.records.slice(0).filter(notDeleted)); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , one: function (id, cb) { | 
					
						
							|  |  |  |       var myRecord; | 
					
						
							|  |  |  |       db.records.slice(0).some(function (r) { | 
					
						
							|  |  |  |         if (id && id === r.id) { | 
					
						
							|  |  |  |           if (notDeleted(r)) { | 
					
						
							|  |  |  |             myRecord = r; | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       process.nextTick(function () { | 
					
						
							|  |  |  |         cb(null, myRecord); | 
					
						
							| 
									
										
										
										
											2018-01-10 08:14:05 +00:00
										 |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , get: function (query, cb) { | 
					
						
							|  |  |  |       var myRecords = db.records.slice(0).filter(function (r) { | 
					
						
							| 
									
										
										
										
											2017-11-05 09:16:27 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-10 08:14:05 +00:00
										 |  |  |         if ('string' !== typeof r.name) { | 
					
						
							|  |  |  |           return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-11-05 09:16:27 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-10 08:14:05 +00:00
										 |  |  |         // TODO use IN in masterquest (or implement OR)
 | 
					
						
							|  |  |  |         // Only return single-level wildcard?
 | 
					
						
							|  |  |  |         if (query.name === r.name || ('*.' + query.name.split('.').slice(1).join('.')) === r.name) { | 
					
						
							| 
									
										
										
										
											2018-01-29 14:54:03 -07:00
										 |  |  |           if (notDeleted(r)) { | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-01-10 08:14:05 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       process.nextTick(function () { | 
					
						
							|  |  |  |         cb(null, myRecords); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-23 15:21:20 -07:00
										 |  |  |   , save: function (record, cb) { | 
					
						
							| 
									
										
										
										
											2018-01-26 01:42:24 -07:00
										 |  |  |       function touchZone(err, r) { | 
					
						
							|  |  |  |         if (err) { cb(err); } | 
					
						
							|  |  |  |         if (!r) { cb(null, null); } | 
					
						
							|  |  |  |         engine.zones.touch({ name: r.zone }, cb); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-23 15:21:20 -07:00
										 |  |  |       if (record.id) { | 
					
						
							|  |  |  |         console.log('update record!'); | 
					
						
							| 
									
										
										
										
											2018-01-26 01:42:24 -07:00
										 |  |  |         engine.records.update(record, touchZone); | 
					
						
							| 
									
										
										
										
											2018-01-23 15:21:20 -07:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2018-01-26 01:42:24 -07:00
										 |  |  |         engine.records.create(record, touchZone); | 
					
						
							| 
									
										
										
										
											2018-01-23 15:21:20 -07:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , 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) { | 
					
						
							| 
									
										
										
										
											2018-01-26 01:42:24 -07:00
										 |  |  |         var keys = [ 'name', 'id', 'zone', 'revokedAt', 'changedAt', 'insertedAt', 'updatedAt', 'deletedAt' ]; | 
					
						
							|  |  |  |         if (-1 !== keys.indexOf(key)) { return; } | 
					
						
							| 
									
										
										
										
											2018-01-23 15:21:20 -07:00
										 |  |  |         if (existing[key] !== record[key]) { | 
					
						
							|  |  |  |           dirty = true; | 
					
						
							|  |  |  |           console.log(existing[key], record[key]); | 
					
						
							|  |  |  |           existing[key] = record[key]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-26 01:42:24 -07:00
										 |  |  |       record.updatedAt = new Date().valueOf(); // toISOString(); // Math.round(Date.now() / 1000);
 | 
					
						
							| 
									
										
										
										
											2018-01-23 15:21:20 -07:00
										 |  |  |       if (dirty) { | 
					
						
							|  |  |  |         record.changedAt = record.updatedAt; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       console.log('saving...'); | 
					
						
							|  |  |  |       db.save(function (err) { | 
					
						
							|  |  |  |         cb(err, !err && existing || null); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-26 01:42:24 -07:00
										 |  |  |   , create: function (record, cb) { | 
					
						
							|  |  |  |       var obj = { id: crypto.randomBytes(16).toString('hex') }; | 
					
						
							|  |  |  |       console.log('found existing record'); | 
					
						
							|  |  |  |       console.log(record); | 
					
						
							|  |  |  |       //var keys = [ 'name', 'id', 'zone', 'revokedAt', 'changedAt', 'insertedAt', 'updatedAt', 'deletedAt' ];
 | 
					
						
							|  |  |  |       //var okeys = [ 'name', 'zone', 'admin', 'data', 'expiration', 'minimum', 'serial', 'retry', 'refresh', 'ttl', 'type' ]; // primary
 | 
					
						
							|  |  |  |       var okeys = [ 'name', 'zone', 'type', 'data', 'class', 'ttl', 'address' | 
					
						
							|  |  |  |                   , 'exchange', 'priority', 'port', 'value', 'tag', 'flag', 'aname' ]; | 
					
						
							|  |  |  |       okeys.forEach(function (key) { | 
					
						
							|  |  |  |         if ('undefined' !== typeof record[key]) { | 
					
						
							|  |  |  |           obj[key] = record[key]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       record.updatedAt = new Date().valueOf(); // toISOString(); // Math.round(Date.now() / 1000);
 | 
					
						
							|  |  |  |       //record.changedAt = record.updatedAt;
 | 
					
						
							|  |  |  |       record.insertedAt = record.updatedAt; | 
					
						
							|  |  |  |       record.createdAt = record.updatedAt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       console.log('saving new...'); | 
					
						
							|  |  |  |       db.records.push(record); | 
					
						
							|  |  |  |       db.save(function (err) { | 
					
						
							|  |  |  |         cb(err, record); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-29 14:54:03 -07:00
										 |  |  |   , destroy: function (id, cb) { | 
					
						
							|  |  |  |       var record; | 
					
						
							|  |  |  |       db.records.some(function (r/*, i*/) { | 
					
						
							|  |  |  |         if (id === r.id) { | 
					
						
							|  |  |  |           record = r; | 
					
						
							|  |  |  |           r.deletedAt = Date.now(); | 
					
						
							|  |  |  |           //record = db.records.splice(i, 1);
 | 
					
						
							|  |  |  |           return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       process.nextTick(function () { | 
					
						
							|  |  |  |         db.save(function (err) { | 
					
						
							|  |  |  |           cb(err, record); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-11-05 09:16:27 -07:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return engine; | 
					
						
							|  |  |  | }; |