Skip to content

Instantly share code, notes, and snippets.

@colinbate
Last active January 5, 2016 03:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save colinbate/517144b2bfc2584575e7 to your computer and use it in GitHub Desktop.
Save colinbate/517144b2bfc2584575e7 to your computer and use it in GitHub Desktop.
module['exports'] = function karaokeSongRequests (hook) {
var jwt = require('jsonwebtoken'),
clientId = hook.env.ksr_client,
secret = require('base64url').toBuffer(hook.env.ksr_secret),
token = hook.req.headers.authorization && hook.req.headers.authorization.replace(/^Bearer\s+/, ''),
store = hook.datastore,
action = hook.params.action || 'get',
user = {},
errorRes = function (res, msg, code) {
res.statusCode = code || 500;
res.end(msg);
},
jsonRes = function (res, data) {
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(data || {success: true}));
},
needArrayPayload = function (payload) {
return !payload || !Array.isArray(payload);
},
needRequestPayload = function (payload) {
return !payload || !payload.email || !payload.key || !payload.title || !payload.artist;
},
mapFromPayload = function (delegate) {
return function (input, payload) {
var rMap = new Map(input);
payload.forEach(function (pl) { delegate.call(null, rMap, pl); });
var result = [];
rMap.forEach(function (v, k) {
result.push([k, v]);
});
return result;
};
},
adminAction = function (thunk, arg1, arg2) {
return function (res, payload, store, user) {
if (!user.authenticated) { return errorRes(res, 'Action requires authentication', 401); }
if (!user.admin) { return errorRes(res, 'Action requires admin access.', 403); }
return thunk(arg1, arg2, res, payload, store);
};
},
getSetAction = function (transform, isPayloadInvalid, res, payload, store, boomerang) {
if (isPayloadInvalid && isPayloadInvalid(payload)) { return errorRes('Invalid payload provided.', 400); }
store.get(store.KEY, function (err, result) {
if (err) { return errorRes(res, err.message); }
result = result || [];
result = transform(result, payload);
store.set(store.KEY, result, function (err) {
if (err) { return errorRes(res, err.message); }
return jsonRes(res, boomerang ? payload : void 0);
});
});
},
actions = {
archive: adminAction(getSetAction, function (input) {
return input.filter(function (r) {
return !r[1].completed;
});
}),
remove: adminAction(getSetAction, mapFromPayload(function (rMap, payloadItem) {
rMap.delete(payloadItem);
}), needArrayPayload),
fulfill: adminAction(getSetAction, mapFromPayload(function (rMap, payloadItem) {
rMap.get(payloadItem).completed = (new Date).toJSON();
}), needArrayPayload),
purge: adminAction(function (x, y, res, p, store) {
store.del(store.KEY, function (err) {
if (err) { return errorRes(res, err.message); }
jsonRes(res);
});
}),
add: function (res, payload, store) {
return getSetAction(function (input) {
input.push([payload.key, payload]);
return input;
}, needRequestPayload, res, payload, store, true);
},
get: function (res, payload, store, user) {
store.get(store.KEY, function(err, result) {
if (err) { return errorRes(res, err.message); }
result = result || [];
var pending = [], complete = [];
result.forEach(function (v) {
if (!user.admin) {
delete v[1].name;
delete v[1].email;
}
if (!v[1].completed) {
pending.push(v);
} else if (user.admin) {
complete.push(v);
}
});
return jsonRes(res, {list: pending, fulfilled: complete});
});
}
};
// Check token
if (token) {
try {
user = jwt.verify(token, secret, {audience: clientId});
user.authenticated = true;
} catch (e) {
errorRes(hook.res, 'Invalid user token', 401);
return;
}
}
// Perform action
store.KEY = 'karaoke-requests';
if (action in actions) {
return actions[action](hook.res, hook.params.payload, store, user);
}
return errorRes(hook.res, 'Unknown action: ' + action, 400);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment