-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
129 lines (112 loc) · 4.25 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
var _ = require("lodash");
var rpc = {
methodName:"rpc",
rpcEntries:{},
wrap:function(id, obj, whitelist, sync, data){
if(_.isObject(id)){
var entry = id;
rpc.rpcEntries[entry.id] = entry;
} else {
rpc.rpcEntries[id] = {id:id, obj:obj, whitelist:whitelist, sync:sync, data:data};
}
},
middleware:function(req, res, next){
var urlSplit = req.url.split("/");
//If they're not after the rpc, send them on.
if(urlSplit[1] !== rpc.methodName){
return next();
}
var id = urlSplit[2];
var operation = urlSplit[3];
var args = req.body;
rpc.call(req, res, id, operation, args);
},
call:function(req, res, id, operation, args){
console.log("==== Operation called with:======")
console.log("ID:", id);
console.log("Operation:", operation);
console.log("Arguments:", (args && args.join && args.join()) || args);
var obj = rpc.rpcEntries[id].obj;
var whitelist = rpc.rpcEntries[id].whitelist;
var data = !!rpc.rpcEntries[id].data;
var async = !rpc.rpcEntries[id].sync; //async will be default
//If the arguments provided arn't in array format throw error;
if(args && !_.isArray(args)){
res.send(401, "The request body must be in array format");
console.log("Error:", "Arguments not array");
console.log("=================================");
return;
}
//If they're tring to reach an rpc object that dosn't exist...
if(!obj){
res.send(404, "No rpc object under that id");
console.log("Error:", "No object under that id");
console.log("=================================");
return;
}
//If they're trying to reach an operation that dosn't exist...
if(!obj[operation]){
res.send(404, "Operation not found");
console.log("Error:", "Operation not found");
console.log("=================================");
return;
}
//Whitelist must be deliberatly set to false to be ignored
//If the operation on the rpc object they're trying to reach dosn't exist...
if(whitelist !== false && !_.includes(whitelist, operation)){
res.send(403, "Forbidden operation");
console.log("Error:", "Forbidden operation");
console.log("=================================");
return;
}
//If they're not targeting a value and we're cool with returning data, just send them back the whole thing.
if(!data && !_.isFunction(obj[operation])){
res.send(401, "The operation is not a function");
console.log("Error:", "Operation not function");
console.log("=================================");
return;
}
//Build the list of arguments for our function. If it's syncronous, don't include callback.
if(args){
args = async ? args.concat([onDone, req, res]) : args.concat([req, res]);
} else {
args = async ? [onDone, req, res] : [req, res];
}
//Call our function.
if(async){
obj[operation].apply(obj, args);
} else {
try{
var result = obj[operation].apply(obj, args);
handleSuccess(result);
} catch (err){
handleFailure(err);
}
}
function onDone(err, result){
if(err){
handleFailure(err);
} else {
handleSuccess(result);
}
}
function handleFailure(err){
console.log("Error:", err);
console.log("=================================");
if(!err.status){
res.status(400).send({status:400, error:err});
} else {
res.status(err.status).send(err);
}
}
function handleSuccess(result){
console.log("Result:", result);
console.log("=================================");
res.status(200).send(result);
}
}
}
module.exports = {
middleware:rpc.middleware,
wrap:rpc.wrap
};