-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathverify.js
146 lines (128 loc) · 4.44 KB
/
verify.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
var url = require('url');
var Gun = require('../gun');
/**
* Verify the origin
*
* @param {RegExp|Array|String|Function} allowed The allowed origins
* @param {String} origin String representation of the request URL
* @return {Boolean} Whether or not the origin is valid
*/
var verifyOrigin = function(allowed, origin) {
var isValid = false;
if (allowed instanceof RegExp) {
isValid = allowed.test(origin);
} else if (allowed instanceof Array) {
isValid = allowed.indexOf(origin) !== -1;
} else if (allowed instanceof Function) {
isValid = allowed(origin);
} else {
isValid = allowed === origin;
}
return isValid;
};
/**
* Verify the authentication header
*
* @todo make this callback based
*
* @param {Function|String} check Check option passed in
* @param {String} authToken The auth token passed in query string
* @param {Object} query Full query string as an object
* @return {Boolean} Whether or not the auth header is valid
*/
var verifyAuth = function(check, authToken, query) {
var isValid = false;
if (check instanceof Function) {
isValid = check(authToken, query);
} else {
isValid = check === authToken;
}
return isValid === true;
};
Gun.on('opt', function(context) {
var opt = context.opt || {};
var ws = opt.ws || {};
if (!opt.verify) {
this.to.next(context);
return;
}
/**
* verify when instantiating Gun can contain the following keys:
* allowOrigins: Array|RegExp|String
* auth: String|Function
* authKey: String
* check: Function
*/
var verify = opt.verify;
if (ws.verifyClient && !verify.override) {
throw Error('Cannot override existing verifyClient option in `ws` configuration.');
}
/**
* Attach a verifyClient to the WS configuration.
*
* @param {Object} info Request information
* @param {Function} callback Called when verification is complete
*/
ws.verifyClient = function(info, callback) {
// Callback Definitions
var errorCallback = (errorCode, message) => {
callback(false, errorCode, message);
};
var successCallback = () => {
callback(true);
};
// 0. Verify security
if (verify.requireSecure && !info.secure) {
errorCallback(400, 'Insecure connection');
return;
}
// 1. Verify request origin
if (verify.allowOrigins && !verifyOrigin(verify.allowOrigins, info.origin)) {
errorCallback(403, 'Origin forbidden');
return;
}
// 2. Check authentication
if (verify.auth) {
// Retrieve parameters from the query string
// and convert into an object
var queryUrl = url.parse(info.req.url, true);
queryUrl.query = queryUrl.query || {};
// Get the header defined by the user
// Or use authorization by default.
var token = (verify.authKey)
? queryUrl.query[verify.authKey]
: queryUrl.query.authorization;
// Check the token against the verification function
if (!token || !verifyAuth(verify.auth, token, queryUrl.query)) {
errorCallback(403, 'Forbidden');
return;
}
}
// If no additional verification check is provided,
// simply return true at this point since all
// provided verifications have passed.
if (!verify.check) {
successCallback();
return;
}
// 3. Pass to generic check handler
// This can return a value; alternatively, this can use the
// callback functionality
var isValid = verify.check(info, successCallback, errorCallback);
// Check returned a response, pass this to the callback
// If not, assume the user will call
if (typeof isValid !== 'undefined') {
if (typeof isValid === 'boolean') {
if (isValid === true) {
successCallback();
} else {
errorCallback(400);
}
}
}
};
context.opt.ws = ws;
// Pass to next plugins
this.to.next(context);
});
module.exports = Gun;