This repository has been archived by the owner on Apr 3, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(server): Extract and simplify record retreival/storage, user…
… defined rules. server.js has a whole bunch of mixed concerns, part of which was record retreival and loading/checking user defined rules. This PR extracts record handling logic as well as user defined rules logic into their own modules. Loading/saving records can now be done through a common interface. fetchRecords no longer holds the assumption that an ip address will be passed in. setRecord no longer requires passing in a key as the key is stored on the record, and setRecords now only accepts records instead of it's confusing signature. It's now possible to define non-enumerable properties on a record that are not saved when serialized. I started to use async/await to simplify logic where it made sense as well as started down the path to using native promises in places. Note, no remote tests are modified, so functionality should be the same. This is groundwork to simplify the DataFlow integration where a simple API is needed to fetch records of varying types.
- Loading branch information
Shane Tomlinson
committed
Mar 21, 2019
1 parent
8a7fa30
commit 6f73c3c
Showing
9 changed files
with
490 additions
and
343 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
module.exports = function (mc, reputationService, limits, recordLifetimeSeconds) { | ||
const IpEmailRecord = require('./ip_email_record')(limits) | ||
const EmailRecord = require('./email_record')(limits) | ||
const IpRecord = require('./ip_record')(limits) | ||
const UidRecord = require('./uid_record')(limits) | ||
const SmsRecord = require('./sms_record')(limits) | ||
|
||
/** | ||
* Fetch a single record keyed by `key`, parse the result using `parser`. | ||
* | ||
* @param {String} key | ||
* @param {Function} parser | ||
* @returns {Promise} resolves to a Record when complete | ||
*/ | ||
async function fetchRecord(key, parser) { | ||
const record = await mc.getAsync(key).then(parser, parser) | ||
record.key = key | ||
return record | ||
} | ||
|
||
/** | ||
* Fetch a set of records | ||
* | ||
* @param {Object} config | ||
* @param {String} [object.ip] ip address to fetch | ||
* @param {String} [object.email] email address to fetch | ||
* @param {String} [object.phoneNumber] phone number to fetch | ||
* @param {String} [object.uid] uid to fetch | ||
* @returns {Promise} resolves to an object with the following keys: | ||
* `ipRecord`, `reputation`, `emailRecord`, `ipEmailRecord`, `smsRecord`, and `uidRecord` | ||
*/ | ||
async function fetchRecords(config) { | ||
const records = {} | ||
|
||
const { ip, email, phoneNumber, uid } = config | ||
|
||
if (ip) { | ||
records.ipRecord = await fetchRecord(ip, IpRecord.parse) | ||
records.reputation = await reputationService.get(ip) | ||
} | ||
|
||
// The /checkIpOnly endpoint has no email (or phoneNumber) | ||
if (email) { | ||
records.emailRecord = await fetchRecord(email, EmailRecord.parse) | ||
} | ||
|
||
if (ip && email) { | ||
records.ipEmailRecord = await fetchRecord(ip + email, IpEmailRecord.parse) | ||
} | ||
|
||
// Check against SMS records to make sure that this request can send to this phone number | ||
if (phoneNumber) { | ||
records.smsRecord = await fetchRecord(phoneNumber, SmsRecord.parse) | ||
} | ||
|
||
if (uid) { | ||
records.uidRecord = await fetchRecord(uid, UidRecord.parse) | ||
} | ||
|
||
return records | ||
} | ||
|
||
/** | ||
* Save a record | ||
* | ||
* @param {Record} record | ||
* @returns | ||
*/ | ||
function setRecord(record) { | ||
const lifetime = Math.max(recordLifetimeSeconds, record.getMinLifetimeMS() / 1000) | ||
return mc.setAsync(record.key, marshallRecordForStorage(record), lifetime) | ||
} | ||
|
||
/** | ||
* Marshall a record for persistent storage | ||
* | ||
* @param {Record} record | ||
* @returns {Object} | ||
*/ | ||
function marshallRecordForStorage (record) { | ||
const marshalled = {} | ||
|
||
for (const key of Object.keys(record)) { | ||
if (key !== 'key' && typeof record[key] !== 'function') { | ||
marshalled[key] = record[key] | ||
} | ||
} | ||
|
||
return marshalled | ||
} | ||
|
||
/** | ||
* Save records | ||
* | ||
* @param {Record[]} records to save. | ||
* @returns {Promise} Resolves when complete | ||
*/ | ||
function setRecords(...records) { | ||
return Promise.all(records.map(record => setRecord(record))) | ||
} | ||
|
||
return { | ||
fetchRecord, | ||
fetchRecords, | ||
setRecord, | ||
setRecords | ||
} | ||
} |
Oops, something went wrong.