cloudcms-server 3.2.287 → 3.2.289
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +7 -0
- package/package.json +4 -4
- package/util/auth.js +11 -5
- package/util/proxy-factory.http2-proxy.js +281 -0
- package/util/proxy-factory.js +93 -124
package/index.js
CHANGED
|
@@ -48,6 +48,13 @@ if (process.env.DEFAULT_HTTP_TIMEOUT_MS)
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
// dns fix for Node 17 +
|
|
52
|
+
// see: https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder
|
|
53
|
+
var dns = require("dns");
|
|
54
|
+
if (typeof(dns.setDefaultResultOrder) !== "undefined") {
|
|
55
|
+
dns.setDefaultResultOrder("ipv4first");
|
|
56
|
+
}
|
|
57
|
+
|
|
51
58
|
// default agents
|
|
52
59
|
var HttpKeepAliveAgent = require('agentkeepalive');
|
|
53
60
|
var HttpsKeepAliveAgent = require('agentkeepalive').HttpsAgent;
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": {
|
|
3
3
|
"name": "Gitana Software, Inc.",
|
|
4
|
-
"email": "info@
|
|
5
|
-
"url": "https://
|
|
4
|
+
"email": "info@gitana.io",
|
|
5
|
+
"url": "https://gitana.io"
|
|
6
6
|
},
|
|
7
7
|
"name": "cloudcms-server",
|
|
8
8
|
"description": "Cloud CMS Application Server Module",
|
|
9
|
-
"version": "3.2.
|
|
9
|
+
"version": "3.2.289",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "git://github.com/gitana/cloudcms-server.git"
|
|
@@ -40,12 +40,12 @@
|
|
|
40
40
|
"express-session": "^1.17.3",
|
|
41
41
|
"express-useragent": "^1.0.15",
|
|
42
42
|
"extend-with-super": "^2.0.0",
|
|
43
|
+
"fast-proxy": "^2.2.0",
|
|
43
44
|
"finalhandler": "^1.2.0",
|
|
44
45
|
"gitana": "^1.0.322",
|
|
45
46
|
"handlebars": "^4.4.2",
|
|
46
47
|
"hbs": "^4.0.5",
|
|
47
48
|
"helmet": "^4.6.0",
|
|
48
|
-
"http2-proxy": "^5.0.53",
|
|
49
49
|
"ioredis": "4.28.5",
|
|
50
50
|
"json5": "^1.0.1",
|
|
51
51
|
"jsonwebtoken": "^8.5.1",
|
package/util/auth.js
CHANGED
|
@@ -327,23 +327,29 @@ var syncProfile = exports.syncProfile = function(req, res, strategy, domainId, p
|
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
_LOCK([CACHE_IDENTIFIER], function(err, releaseLockFn) {
|
|
330
|
+
|
|
331
|
+
if (err) {
|
|
332
|
+
try { releaseLockFn(); } catch (e) { }
|
|
333
|
+
return callback(err);
|
|
334
|
+
}
|
|
335
|
+
|
|
330
336
|
_handleSyncUser(req, strategy, settings, key, domainId, providerId, providerUserId, token, refreshToken, userObject, groupsArray, function (err, gitanaUser) {
|
|
331
337
|
|
|
332
338
|
if (err) {
|
|
333
|
-
releaseLockFn();
|
|
339
|
+
try { releaseLockFn(); } catch (e) { }
|
|
334
340
|
return callback(err);
|
|
335
341
|
}
|
|
336
342
|
|
|
337
343
|
// no user found
|
|
338
344
|
if (!gitanaUser) {
|
|
339
|
-
releaseLockFn();
|
|
345
|
+
try { releaseLockFn(); } catch (e) { }
|
|
340
346
|
return callback();
|
|
341
347
|
}
|
|
342
348
|
|
|
343
349
|
_handleConnectAsUser(req, key, gitanaUser, function (err, platform, appHelper, key) {
|
|
344
350
|
|
|
345
351
|
if (err) {
|
|
346
|
-
releaseLockFn();
|
|
352
|
+
try { releaseLockFn(); } catch (e) { }
|
|
347
353
|
return callback(err);
|
|
348
354
|
}
|
|
349
355
|
|
|
@@ -354,8 +360,8 @@ var syncProfile = exports.syncProfile = function(req, res, strategy, domainId, p
|
|
|
354
360
|
"appHelper": appHelper,
|
|
355
361
|
"key": key
|
|
356
362
|
});
|
|
357
|
-
|
|
358
|
-
releaseLockFn();
|
|
363
|
+
|
|
364
|
+
try { releaseLockFn(); } catch (e) { }
|
|
359
365
|
|
|
360
366
|
callback(err, gitanaUser, platform, appHelper, key, platform.getDriver());
|
|
361
367
|
}, gitanaUser);
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
var http = require("http");
|
|
2
|
+
var https = require("https");
|
|
3
|
+
var path = require("path");
|
|
4
|
+
|
|
5
|
+
var auth = require("./auth");
|
|
6
|
+
var util = require("./util");
|
|
7
|
+
|
|
8
|
+
var oauth2 = require("./oauth2")();
|
|
9
|
+
|
|
10
|
+
var urlTool = require("url");
|
|
11
|
+
const finalhandler = require("finalhandler");
|
|
12
|
+
|
|
13
|
+
var LRU = require("lru-cache");
|
|
14
|
+
|
|
15
|
+
var exports = module.exports;
|
|
16
|
+
|
|
17
|
+
var _LOCK = function(lockIdentifiers, workFunction)
|
|
18
|
+
{
|
|
19
|
+
var name = lockIdentifiers.join("_");
|
|
20
|
+
process.locks.lock(name, workFunction);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
var NAMED_PROXY_HANDLERS_CACHE = new LRU({
|
|
24
|
+
max: 200,
|
|
25
|
+
ttl: 1000 * 60 * 60 // 60 minutes
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
var acquireProxyHandler = exports.acquireProxyHandler = function(proxyTarget, pathPrefix, callback)
|
|
29
|
+
{
|
|
30
|
+
var name = path.join(proxyTarget, (pathPrefix || "/"));
|
|
31
|
+
|
|
32
|
+
// is it already in LRU cache?
|
|
33
|
+
// if so hand it back
|
|
34
|
+
var _cachedHandler = NAMED_PROXY_HANDLERS_CACHE[name];
|
|
35
|
+
if (_cachedHandler)
|
|
36
|
+
{
|
|
37
|
+
return callback(null, _cachedHandler);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// take out a thread lock
|
|
41
|
+
_LOCK(["acquireProxyHandler", name], function(err, releaseLockFn) {
|
|
42
|
+
|
|
43
|
+
if (err)
|
|
44
|
+
{
|
|
45
|
+
console.log("Failed to acquire proxy handler: " + name + ", err: ", err);
|
|
46
|
+
|
|
47
|
+
// failed to acquire lock
|
|
48
|
+
return callback(err);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// second check to make sure another thread didn't create the handler in the meantime
|
|
52
|
+
_cachedHandler = NAMED_PROXY_HANDLERS_CACHE[name];
|
|
53
|
+
if (_cachedHandler)
|
|
54
|
+
{
|
|
55
|
+
releaseLockFn();
|
|
56
|
+
return callback(null, _cachedHandler);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// create the proxy handler and cache it into LRU cache
|
|
60
|
+
//console.log("Acquiring proxy handler: " + name + ", for target: " + proxyTarget + " and prefix: " + pathPrefix);
|
|
61
|
+
_cachedHandler = createProxyHandler(proxyTarget, pathPrefix);
|
|
62
|
+
|
|
63
|
+
// store back into LRU cache
|
|
64
|
+
NAMED_PROXY_HANDLERS_CACHE[name] = _cachedHandler;
|
|
65
|
+
|
|
66
|
+
releaseLockFn();
|
|
67
|
+
callback(null, _cachedHandler);
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
var createProxyHandler = function(proxyTarget, pathPrefix)
|
|
75
|
+
{
|
|
76
|
+
const proxy = require("http2-proxy");
|
|
77
|
+
const finalhandler = require('finalhandler')
|
|
78
|
+
|
|
79
|
+
const defaultWebHandler = function(err, req, res) {
|
|
80
|
+
if (err)
|
|
81
|
+
{
|
|
82
|
+
console.log("A web proxy error was caught, path: " + req.path + ", err: ", err);
|
|
83
|
+
try { res.status(500); } catch (e) { }
|
|
84
|
+
try { res.end('Something went wrong while proxying the request.'); } catch (e) { }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
finalhandler(req, res)(err);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// const defaultWsHandler = function(err, req, socket, head) {
|
|
91
|
+
// if (err) {
|
|
92
|
+
// console.error('proxy error (ws)', err);
|
|
93
|
+
// socket.destroy();
|
|
94
|
+
// }
|
|
95
|
+
// };
|
|
96
|
+
|
|
97
|
+
//console.log("Proxy Target: " + proxyTarget);
|
|
98
|
+
|
|
99
|
+
var hostname = urlTool.parse(proxyTarget).hostname;
|
|
100
|
+
var port = urlTool.parse(proxyTarget).port;
|
|
101
|
+
var protocol = urlTool.parse(proxyTarget).protocol;
|
|
102
|
+
|
|
103
|
+
// web
|
|
104
|
+
var webConfig = {};
|
|
105
|
+
webConfig.hostname = hostname;
|
|
106
|
+
webConfig.port = port;
|
|
107
|
+
webConfig.protocol = protocol;
|
|
108
|
+
//webConfig.path = null;
|
|
109
|
+
webConfig.timeout = 120000;
|
|
110
|
+
webConfig.proxyTimeout = 120000;
|
|
111
|
+
webConfig.proxyName = "Cloud CMS UI Proxy";
|
|
112
|
+
webConfig.onReq = function(req, options) {
|
|
113
|
+
|
|
114
|
+
if (!options.headers) {
|
|
115
|
+
options.headers = {};
|
|
116
|
+
}
|
|
117
|
+
var headers = options.headers;
|
|
118
|
+
|
|
119
|
+
if (options.path && options.path.startsWith("/proxy")) {
|
|
120
|
+
options.path = options.path.substring(6);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (pathPrefix) {
|
|
124
|
+
options.path = path.join(pathPrefix, options.path);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// used to auto-assign the client header for /oauth/token requests
|
|
128
|
+
oauth2.autoProxy(req);
|
|
129
|
+
|
|
130
|
+
// copy domain host into "x-cloudcms-domainhost"
|
|
131
|
+
if (req.domainHost) {
|
|
132
|
+
headers["x-cloudcms-domainhost"] = req.domainHost; // this could be "localhost"
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// copy virtual host into "x-cloudcms-virtualhost"
|
|
136
|
+
if (req.virtualHost) {
|
|
137
|
+
headers["x-cloudcms-virtualhost"] = req.virtualHost; // this could be "root.cloudcms.net" or "abc.cloudcms.net"
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// copy deployment descriptor info
|
|
141
|
+
if (req.descriptor)
|
|
142
|
+
{
|
|
143
|
+
if (req.descriptor.tenant)
|
|
144
|
+
{
|
|
145
|
+
if (req.descriptor.tenant.id)
|
|
146
|
+
{
|
|
147
|
+
headers["x-cloudcms-tenant-id"] = req.descriptor.tenant.id;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (req.descriptor.tenant.title)
|
|
151
|
+
{
|
|
152
|
+
headers["x-cloudcms-tenant-title"] = req.descriptor.tenant.title;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (req.descriptor.application)
|
|
157
|
+
{
|
|
158
|
+
if (req.descriptor.application.id)
|
|
159
|
+
{
|
|
160
|
+
headers["x-cloudcms-application-id"] = req.descriptor.application.id;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (req.descriptor.application.title)
|
|
164
|
+
{
|
|
165
|
+
headers["x-cloudcms-application-title"] = req.descriptor.application.title;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// set optional "x-cloudcms-origin" header
|
|
171
|
+
var cloudcmsOrigin = null;
|
|
172
|
+
if (req.virtualHost)
|
|
173
|
+
{
|
|
174
|
+
cloudcmsOrigin = req.virtualHost;
|
|
175
|
+
}
|
|
176
|
+
if (cloudcmsOrigin)
|
|
177
|
+
{
|
|
178
|
+
headers["x-cloudcms-origin"] = cloudcmsOrigin;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// set x-cloudcms-server-version header
|
|
182
|
+
headers["x-cloudcms-server-version"] = process.env.CLOUDCMS_APPSERVER_PACKAGE_VERSION;
|
|
183
|
+
|
|
184
|
+
// keep alive
|
|
185
|
+
//req.headers["connection"] = "keep-alive";
|
|
186
|
+
|
|
187
|
+
// if the incoming request didn't have an "Authorization" header
|
|
188
|
+
// and we have a logged in Gitana User via Auth, then set authorization header to Bearer Access Token
|
|
189
|
+
if (!req.headers["authorization"])
|
|
190
|
+
{
|
|
191
|
+
if (req.gitana_user)
|
|
192
|
+
{
|
|
193
|
+
headers["authorization"] = "Bearer " + req.gitana_user.getDriver().http.accessToken();
|
|
194
|
+
}
|
|
195
|
+
else if (req.gitana_proxy_access_token)
|
|
196
|
+
{
|
|
197
|
+
headers["authorization"] = "Bearer " + req.gitana_proxy_access_token;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
webConfig.onRes = function(req, res, proxyRes) {
|
|
202
|
+
|
|
203
|
+
if (req.gitana_user)
|
|
204
|
+
{
|
|
205
|
+
var chunks = [];
|
|
206
|
+
|
|
207
|
+
// triggers on data receive
|
|
208
|
+
proxyRes.on('data', function(chunk) {
|
|
209
|
+
// add received chunk to chunks array
|
|
210
|
+
chunks.push(chunk);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
proxyRes.on("end", function () {
|
|
214
|
+
|
|
215
|
+
if (proxyRes.statusCode === 401)
|
|
216
|
+
{
|
|
217
|
+
var text = "" + Buffer.concat(chunks);
|
|
218
|
+
if (text && (text.indexOf("invalid_token") > -1) || (text.indexOf("invalid_grant") > -1))
|
|
219
|
+
{
|
|
220
|
+
var identifier = req.identity_properties.provider_id + "/" + req.identity_properties.user_identifier;
|
|
221
|
+
|
|
222
|
+
_LOCK([identifier], function(err, releaseLockFn) {
|
|
223
|
+
|
|
224
|
+
if (err)
|
|
225
|
+
{
|
|
226
|
+
// failed to acquire lock
|
|
227
|
+
console.log("FAILED TO ACQUIRE LOCK", err);
|
|
228
|
+
req.log("FAILED TO ACQUIRE LOCK", err);
|
|
229
|
+
try { releaseLockFn(); } catch (e) { }
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
var cleanup = function (full)
|
|
234
|
+
{
|
|
235
|
+
delete Gitana.APPS[req.identity_properties.token];
|
|
236
|
+
delete Gitana.PLATFORM_CACHE[req.identity_properties.token];
|
|
237
|
+
|
|
238
|
+
if (full) {
|
|
239
|
+
auth.removeUserCacheEntry(identifier);
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
// null out the access token
|
|
244
|
+
// this will force the refresh token to be used to get a new one on the next request
|
|
245
|
+
req.gitana_user.getDriver().http.refresh(function (err) {
|
|
246
|
+
|
|
247
|
+
if (err) {
|
|
248
|
+
cleanup(true);
|
|
249
|
+
req.log("Invalidated auth state for gitana user: " + req.identity_properties.token);
|
|
250
|
+
return releaseLockFn();
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
req.gitana_user.getDriver().reloadAuthInfo(function () {
|
|
254
|
+
cleanup(true);
|
|
255
|
+
req.log("Refreshed token for gitana user: " + req.identity_properties.token);
|
|
256
|
+
releaseLockFn();
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
//res.setHeader('x-powered-by', 'cloudcms');
|
|
267
|
+
res.writeHead(proxyRes.statusCode, proxyRes.headers)
|
|
268
|
+
proxyRes.pipe(res)
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
var proxyRequestHandler = function(req, res) {
|
|
272
|
+
proxy.web(req, res, webConfig, function(err, req, res) {
|
|
273
|
+
defaultWebHandler(err, req, res);
|
|
274
|
+
});
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// cookie domain rewrite?
|
|
278
|
+
// not needed - this is handled intrinsically by http2-proxy
|
|
279
|
+
|
|
280
|
+
return proxyRequestHandler;
|
|
281
|
+
};
|
package/util/proxy-factory.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
var http = require("http");
|
|
2
|
-
var https = require("https");
|
|
1
|
+
// var http = require("http");
|
|
2
|
+
// var https = require("https");
|
|
3
3
|
var path = require("path");
|
|
4
4
|
|
|
5
5
|
var auth = require("./auth");
|
|
6
|
-
var util = require("./util");
|
|
6
|
+
// var util = require("./util");
|
|
7
7
|
|
|
8
8
|
var oauth2 = require("./oauth2")();
|
|
9
9
|
|
|
10
|
-
var urlTool = require("url");
|
|
11
|
-
const finalhandler = require("finalhandler");
|
|
12
|
-
|
|
13
10
|
var LRU = require("lru-cache");
|
|
14
11
|
|
|
15
12
|
var exports = module.exports;
|
|
@@ -73,59 +70,95 @@ var acquireProxyHandler = exports.acquireProxyHandler = function(proxyTarget, pa
|
|
|
73
70
|
|
|
74
71
|
var createProxyHandler = function(proxyTarget, pathPrefix)
|
|
75
72
|
{
|
|
76
|
-
const proxy = require(
|
|
77
|
-
|
|
73
|
+
const { proxy, close } = require('fast-proxy')({
|
|
74
|
+
base: proxyTarget,
|
|
75
|
+
cacheURLs: 0,
|
|
76
|
+
http2: true,
|
|
77
|
+
//undici: true
|
|
78
|
+
});
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
var proxyOptions = {};
|
|
81
|
+
proxyOptions.onResponse = function(req, res, stream) {
|
|
82
|
+
|
|
83
|
+
if (req.gitana_user)
|
|
81
84
|
{
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// const defaultWsHandler = function(err, req, socket, head) {
|
|
91
|
-
// if (err) {
|
|
92
|
-
// console.error('proxy error (ws)', err);
|
|
93
|
-
// socket.destroy();
|
|
94
|
-
// }
|
|
95
|
-
// };
|
|
96
|
-
|
|
97
|
-
//console.log("Proxy Target: " + proxyTarget);
|
|
98
|
-
|
|
99
|
-
var hostname = urlTool.parse(proxyTarget).hostname;
|
|
100
|
-
var port = urlTool.parse(proxyTarget).port;
|
|
101
|
-
var protocol = urlTool.parse(proxyTarget).protocol;
|
|
85
|
+
var chunks = [];
|
|
86
|
+
|
|
87
|
+
// triggers on data receive
|
|
88
|
+
stream.on('data', function(chunk) {
|
|
89
|
+
console.log("DATA!");
|
|
90
|
+
// add received chunk to chunks array
|
|
91
|
+
chunks.push(chunk);
|
|
92
|
+
});
|
|
102
93
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
94
|
+
stream.on("end", function () {
|
|
95
|
+
|
|
96
|
+
if (stream.statusCode === 401)
|
|
97
|
+
{
|
|
98
|
+
var text = "" + Buffer.concat(chunks);
|
|
99
|
+
if (text && (text.indexOf("invalid_token") > -1) || (text.indexOf("invalid_grant") > -1))
|
|
100
|
+
{
|
|
101
|
+
var identifier = req.identity_properties.provider_id + "/" + req.identity_properties.user_identifier;
|
|
102
|
+
|
|
103
|
+
_LOCK([identifier], function(err, releaseLockFn) {
|
|
104
|
+
|
|
105
|
+
if (err)
|
|
106
|
+
{
|
|
107
|
+
// failed to acquire lock
|
|
108
|
+
console.log("FAILED TO ACQUIRE LOCK", err);
|
|
109
|
+
req.log("FAILED TO ACQUIRE LOCK", err);
|
|
110
|
+
try { releaseLockFn(); } catch (e) { }
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
var cleanup = function (full)
|
|
115
|
+
{
|
|
116
|
+
delete Gitana.APPS[req.identity_properties.token];
|
|
117
|
+
delete Gitana.PLATFORM_CACHE[req.identity_properties.token];
|
|
118
|
+
|
|
119
|
+
if (full) {
|
|
120
|
+
auth.removeUserCacheEntry(identifier);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// null out the access token
|
|
125
|
+
// this will force the refresh token to be used to get a new one on the next request
|
|
126
|
+
req.gitana_user.getDriver().http.refresh(function (err) {
|
|
127
|
+
|
|
128
|
+
if (err) {
|
|
129
|
+
cleanup(true);
|
|
130
|
+
req.log("Invalidated auth state for gitana user: " + req.identity_properties.token);
|
|
131
|
+
return releaseLockFn();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
req.gitana_user.getDriver().reloadAuthInfo(function () {
|
|
135
|
+
cleanup(true);
|
|
136
|
+
req.log("Refreshed token for gitana user: " + req.identity_properties.token);
|
|
137
|
+
releaseLockFn();
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
}
|
|
144
|
+
});
|
|
121
145
|
}
|
|
122
146
|
|
|
123
|
-
|
|
124
|
-
|
|
147
|
+
//res.setHeader('x-powered-by', 'cloudcms');
|
|
148
|
+
if (stream.statusCode && stream.headers) {
|
|
149
|
+
res.writeHead(stream.statusCode, stream.headers)
|
|
125
150
|
}
|
|
126
151
|
|
|
152
|
+
stream.pipe(res)
|
|
153
|
+
};
|
|
154
|
+
proxyOptions.rewriteRequestHeaders = function(req, headers)
|
|
155
|
+
{
|
|
127
156
|
// used to auto-assign the client header for /oauth/token requests
|
|
128
157
|
oauth2.autoProxy(req);
|
|
158
|
+
if (req.headers && req.headers.authorization)
|
|
159
|
+
{
|
|
160
|
+
headers["authorization"] = req.headers.authorization;
|
|
161
|
+
}
|
|
129
162
|
|
|
130
163
|
// copy domain host into "x-cloudcms-domainhost"
|
|
131
164
|
if (req.domainHost) {
|
|
@@ -197,85 +230,21 @@ var createProxyHandler = function(proxyTarget, pathPrefix)
|
|
|
197
230
|
headers["authorization"] = "Bearer " + req.gitana_proxy_access_token;
|
|
198
231
|
}
|
|
199
232
|
}
|
|
200
|
-
};
|
|
201
|
-
webConfig.onRes = function(req, res, proxyRes) {
|
|
202
|
-
|
|
203
|
-
if (req.gitana_user)
|
|
204
|
-
{
|
|
205
|
-
var chunks = [];
|
|
206
|
-
|
|
207
|
-
// triggers on data receive
|
|
208
|
-
proxyRes.on('data', function(chunk) {
|
|
209
|
-
// add received chunk to chunks array
|
|
210
|
-
chunks.push(chunk);
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
proxyRes.on("end", function () {
|
|
214
|
-
|
|
215
|
-
if (proxyRes.statusCode === 401)
|
|
216
|
-
{
|
|
217
|
-
var text = "" + Buffer.concat(chunks);
|
|
218
|
-
if (text && (text.indexOf("invalid_token") > -1) || (text.indexOf("invalid_grant") > -1))
|
|
219
|
-
{
|
|
220
|
-
var identifier = req.identity_properties.provider_id + "/" + req.identity_properties.user_identifier;
|
|
221
|
-
|
|
222
|
-
_LOCK([identifier], function(err, releaseLockFn) {
|
|
223
|
-
|
|
224
|
-
if (err)
|
|
225
|
-
{
|
|
226
|
-
// failed to acquire lock
|
|
227
|
-
console.log("FAILED TO ACQUIRE LOCK", err);
|
|
228
|
-
req.log("FAILED TO ACQUIRE LOCK", err);
|
|
229
|
-
try { releaseLockFn(); } catch (e) { }
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
var cleanup = function (full)
|
|
234
|
-
{
|
|
235
|
-
delete Gitana.APPS[req.identity_properties.token];
|
|
236
|
-
delete Gitana.PLATFORM_CACHE[req.identity_properties.token];
|
|
237
|
-
|
|
238
|
-
if (full) {
|
|
239
|
-
auth.removeUserCacheEntry(identifier);
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
// null out the access token
|
|
244
|
-
// this will force the refresh token to be used to get a new one on the next request
|
|
245
|
-
req.gitana_user.getDriver().http.refresh(function (err) {
|
|
246
|
-
|
|
247
|
-
if (err) {
|
|
248
|
-
cleanup(true);
|
|
249
|
-
req.log("Invalidated auth state for gitana user: " + req.identity_properties.token);
|
|
250
|
-
return releaseLockFn();
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
req.gitana_user.getDriver().reloadAuthInfo(function () {
|
|
254
|
-
cleanup(true);
|
|
255
|
-
req.log("Refreshed token for gitana user: " + req.identity_properties.token);
|
|
256
|
-
releaseLockFn();
|
|
257
|
-
});
|
|
258
|
-
});
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
233
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
234
|
+
return headers;
|
|
235
|
+
};
|
|
236
|
+
// rewrite response headers
|
|
237
|
+
proxyOptions.rewriteHeaders = function(headers)
|
|
238
|
+
{
|
|
239
|
+
return headers;
|
|
269
240
|
};
|
|
270
241
|
|
|
242
|
+
//////////////////////////////////////////////////////////////////////////
|
|
243
|
+
|
|
271
244
|
var proxyRequestHandler = function(req, res) {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
});
|
|
245
|
+
|
|
246
|
+
proxy(req, res, pathPrefix, proxyOptions);
|
|
275
247
|
};
|
|
276
248
|
|
|
277
|
-
// cookie domain rewrite?
|
|
278
|
-
// not needed - this is handled intrinsically by http2-proxy
|
|
279
|
-
|
|
280
249
|
return proxyRequestHandler;
|
|
281
250
|
};
|