UNPKG

lds-connect-proxy

Version:

A node.js service to to proxy the ldsconnect.org API

138 lines (118 loc) 3.6 kB
'use strict'; var request = require('request') , apiEndpoints // XXX Poor man's cache needs upgrading , cache = {} , staleAt = 60 * 60 * 1000 ; apiEndpoints = [ // need expansion '/api/ldsorg/me' , '/api/ldsorg/me/household' , '/api/ldsorg/me/ward' , '/api/ldsorg/me/stake' // okay , '/api/ldsorg/stakes/:stakeUnitNo/wards/:wardUnitNo/households/:householdId' , '/api/ldsorg/stakes/:stakeUnitNo/wards/:wardUnitNo/photo-list' , '/api/ldsorg/stakes/:stakeUnitNo/wards/:wardUnitNo/member-list' , '/api/ldsorg/stakes/:stakeUnitNo/wards/:wardUnitNo/roster' , '/api/ldsorg/stakes/:stakeUnitNo/wards/:wardUnitNo/info' , '/api/ldsorg/stakes/:stakeUnitNo/wards/:wardUnitNo' , '/api/ldsorg/stakes/:stakeUnitNo' // new LDS Connect APIs , '/api/ldsconnect/stakes/:stakeUnitNo/wards/:wardUnitNo/photos' , '/api/ldsconnect/stakes/:stakeUnitNo/wards/:wardUnitNo/info' , '/api/ldsconnect/stakes/:stakeUnitNo/photos' , '/api/ldsconnect/stakes/:stakeUnitNo/info' , '/api/ldsconnect/me' ]; function getCache(accessToken, mid, url, fn) { url = url.replace(/ldsorg\/me(\b.*)/, 'ldsorg/' + mid + '$1'); fn( null , cache[accessToken] && cache[accessToken][url] && cache[accessToken][url].result , cache[accessToken] && cache[accessToken][url] && cache[accessToken][url].updated); } module.exports.getCache = getCache; function getUrl(mid, accessToken, url, fn) { var options ; options = { //url: 'http://beta.ldsconnect.org:3000' + url url: 'https://ldsconnect.org' + url , headers: { 'Authorization': 'Bearer ' + accessToken } }; function callback(error, response, body) { if (error || response.statusCode !== 200) { fn(error || body, null); return; } url = url.replace(/ldsorg\/me(\b.*)/, 'ldsorg/' + mid + '$1'); // TODO smarter, but still safe caching cache[accessToken] = cache[accessToken] || {}; cache[accessToken][url] = { updated: Date.now() , result: JSON.parse(body) }; clearTimeout(cache[accessToken].timeoutToken); cache[accessToken].timeoutToken = setTimeout(function () { delete cache[accessToken]; }, staleAt); fn(null, body); } request(options, callback); } module.exports.getUrl = getUrl; function forwardOauthRequest(retrieveToken, retrieveUid, req, res) { var url = req.url , accessToken = retrieveToken(req) , mid = retrieveUid(req) ; if (!accessToken || !mid) { res.send({ error: { message: "Not logged in, duh!" } }); return; } getCache(accessToken, mid, req.url, function (err, result, updated) { var now = Date.now() //, url = req.url ; function fin(body) { body = body || '{ "error": "unknown error" }'; if (!body) { console.error(req.url); } if ('string' === typeof body) { res.end(body); } else { res.send(body); } } if (!result) { getUrl(mid, accessToken, url, function (err, data) { fin(err && ('error: ' + err) || data); }); } else if (now - updated > staleAt) { getUrl(mid, accessToken, req.url, function (err, data) { fin(err && ('error: ' + err) || data); }); } else if (now - updated > staleAt / 2) { getUrl(mid, accessToken, req.url, function () {}); fin(result); } else { fin(result); } }); } module.exports.create = function (retrieveToken, retrieveUid) { return function (rest) { apiEndpoints.forEach(function (url) { rest.get(url, forwardOauthRequest.bind(null, retrieveToken, retrieveUid)); }); }; };