cloudcms-server 0.9.301 → 3.2.280
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/.last_command +7 -0
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/broadcast/providers/redis.js +24 -49
- package/clients/nrp.js +117 -0
- package/clients/redis.js +64 -0
- package/framework/controllers.js +4 -4
- package/index.js +13 -10
- package/insight/insight.js +1 -1
- package/launchpad/index.js +174 -11
- package/launchpad/launchers/cluster.js +103 -110
- package/launchpad/launchers/redis.js +70 -0
- package/launchpad/launchers/single.js +36 -22
- package/locks/locks.js +53 -7
- package/locks/providers/cluster.js +3 -1
- package/locks/providers/memory.js +10 -7
- package/locks/providers/redis.js +62 -82
- package/middleware/admin/admin.js +2 -2
- package/middleware/authentication/adapters/session.js +11 -8
- package/middleware/authentication/authentication.js +28 -16
- package/middleware/authentication/authenticators/default.js +5 -2
- package/middleware/authentication/authenticators/session.js +5 -2
- package/middleware/authentication/providers/saml.js +1 -1
- package/middleware/authorization/authorization.js +11 -8
- package/middleware/awareness/awareness.js +51 -29
- package/middleware/awareness/plugins/editorial.js +4 -4
- package/middleware/awareness/providers/abstract-async.js +107 -84
- package/middleware/awareness/providers/abstract.js +1 -1
- package/middleware/awareness/providers/memory.js +0 -14
- package/middleware/awareness/providers/redis.js +186 -279
- package/middleware/cache/providers/redis.js +127 -89
- package/middleware/cloudcms/cloudcms.js +22 -16
- package/middleware/form/form.js +2 -2
- package/middleware/proxy/proxy.js +7 -21
- package/middleware/stores/stores.js +2 -2
- package/middleware/virtual-config/virtual-config.js +7 -7
- package/middleware/wcm/wcm.js +4 -4
- package/package.json +54 -52
- package/server/index.js +517 -399
- package/server/standalone.js +9 -0
- package/temp/clusterlock/index.js +3 -3
- package/temp/clusterlock/package.json +1 -1
- package/temp/passport-saml/LICENSE +23 -0
- package/temp/passport-saml/README.md +406 -0
- package/temp/passport-saml/lib/node-saml/algorithms.d.ts +5 -0
- package/temp/passport-saml/lib/node-saml/algorithms.js +41 -0
- package/temp/passport-saml/lib/node-saml/algorithms.js.map +1 -0
- package/temp/passport-saml/lib/node-saml/index.d.ts +3 -0
- package/temp/passport-saml/lib/node-saml/index.js +6 -0
- package/temp/passport-saml/lib/node-saml/index.js.map +1 -0
- package/temp/passport-saml/lib/node-saml/inmemory-cache-provider.d.ts +45 -0
- package/temp/passport-saml/lib/node-saml/inmemory-cache-provider.js +86 -0
- package/temp/passport-saml/lib/node-saml/inmemory-cache-provider.js.map +1 -0
- package/temp/passport-saml/lib/node-saml/saml-post-signing.d.ts +3 -0
- package/temp/passport-saml/lib/node-saml/saml-post-signing.js +15 -0
- package/temp/passport-saml/lib/node-saml/saml-post-signing.js.map +1 -0
- package/temp/passport-saml/lib/node-saml/saml.d.ts +77 -0
- package/temp/passport-saml/lib/node-saml/saml.js +1170 -0
- package/temp/passport-saml/lib/node-saml/saml.js.map +1 -0
- package/temp/passport-saml/lib/node-saml/types.d.ts +95 -0
- package/temp/passport-saml/lib/node-saml/types.js +8 -0
- package/temp/passport-saml/lib/node-saml/types.js.map +1 -0
- package/temp/passport-saml/lib/node-saml/utility.d.ts +3 -0
- package/temp/passport-saml/lib/node-saml/utility.js +19 -0
- package/temp/passport-saml/lib/node-saml/utility.js.map +1 -0
- package/temp/passport-saml/lib/node-saml/xml.d.ts +21 -0
- package/temp/passport-saml/lib/node-saml/xml.js +140 -0
- package/temp/passport-saml/lib/node-saml/xml.js.map +1 -0
- package/temp/passport-saml/lib/passport-saml/index.d.ts +6 -0
- package/temp/passport-saml/lib/passport-saml/index.js +11 -0
- package/temp/passport-saml/lib/passport-saml/index.js.map +1 -0
- package/temp/passport-saml/lib/passport-saml/multiSamlStrategy.d.ts +13 -0
- package/temp/passport-saml/lib/passport-saml/multiSamlStrategy.js +63 -0
- package/temp/passport-saml/lib/passport-saml/multiSamlStrategy.js.map +1 -0
- package/temp/passport-saml/lib/passport-saml/strategy.d.ts +20 -0
- package/temp/passport-saml/lib/passport-saml/strategy.js +167 -0
- package/temp/passport-saml/lib/passport-saml/strategy.js.map +1 -0
- package/temp/passport-saml/lib/passport-saml/types.d.ts +51 -0
- package/temp/passport-saml/lib/passport-saml/types.js +11 -0
- package/temp/passport-saml/lib/passport-saml/types.js.map +1 -0
- package/temp/passport-saml/package.json +96 -0
- package/util/auth.js +1 -1
- package/util/cloudcms.js +72 -93
- package/util/proxy-factory.js +230 -260
- package/util/redis.js +113 -0
- package/util/renditions.js +1 -1
- package/util/util.js +15 -2
- package/launchpad/launchers/sticky-cluster.js +0 -43
- package/web/cms/ice.js +0 -109
- package/web/cms/preview.js +0 -106
- package/web/socket.io/socket.io.js +0 -2
package/util/proxy-factory.js
CHANGED
|
@@ -2,20 +2,20 @@ var http = require("http");
|
|
|
2
2
|
var https = require("https");
|
|
3
3
|
var path = require("path");
|
|
4
4
|
|
|
5
|
-
var httpProxy = require("http-proxy");
|
|
6
|
-
|
|
7
5
|
var auth = require("./auth");
|
|
8
6
|
var util = require("./util");
|
|
9
7
|
|
|
10
8
|
var oauth2 = require("./oauth2")();
|
|
11
9
|
|
|
12
10
|
var urlTool = require("url");
|
|
11
|
+
const finalhandler = require("finalhandler");
|
|
13
12
|
|
|
14
13
|
var exports = module.exports;
|
|
15
14
|
|
|
16
15
|
var _LOCK = function(lockIdentifiers, workFunction)
|
|
17
16
|
{
|
|
18
|
-
|
|
17
|
+
var name = lockIdentifiers.join("_");
|
|
18
|
+
process.locks.lock(name, workFunction);
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
var NAMED_PROXY_HANDLERS_CACHE = require("lru-cache")({
|
|
@@ -34,9 +34,15 @@ var acquireProxyHandler = exports.acquireProxyHandler = function(proxyTarget, pa
|
|
|
34
34
|
{
|
|
35
35
|
return callback(null, _cachedHandler);
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
// take out a thread lock
|
|
39
|
-
_LOCK(["acquireProxyHandler", name], function(releaseLockFn) {
|
|
39
|
+
_LOCK(["acquireProxyHandler", name], function(err, releaseLockFn) {
|
|
40
|
+
|
|
41
|
+
if (err)
|
|
42
|
+
{
|
|
43
|
+
// failed to acquire lock
|
|
44
|
+
return callback(err);
|
|
45
|
+
}
|
|
40
46
|
|
|
41
47
|
// second check to make sure another thread didn't create the handler in the meantime
|
|
42
48
|
_cachedHandler = NAMED_PROXY_HANDLERS_CACHE[name];
|
|
@@ -48,7 +54,7 @@ var acquireProxyHandler = exports.acquireProxyHandler = function(proxyTarget, pa
|
|
|
48
54
|
|
|
49
55
|
// create the proxy handler and cache it into LRU cache
|
|
50
56
|
_cachedHandler = createProxyHandler(proxyTarget, pathPrefix);
|
|
51
|
-
|
|
57
|
+
|
|
52
58
|
// store back into LRU cache
|
|
53
59
|
NAMED_PROXY_HANDLERS_CACHE[name] = _cachedHandler;
|
|
54
60
|
|
|
@@ -57,134 +63,74 @@ var acquireProxyHandler = exports.acquireProxyHandler = function(proxyTarget, pa
|
|
|
57
63
|
});
|
|
58
64
|
};
|
|
59
65
|
|
|
60
|
-
var createProxyHandler = function(proxyTarget, pathPrefix)
|
|
61
|
-
{
|
|
62
|
-
////////////////////////////////////////////////////////////////////////////
|
|
63
|
-
//
|
|
64
|
-
// HTTP/HTTPS Proxy Server to Cloud CMS
|
|
65
|
-
// Facilitates Cross-Domain communication between Browser and Cloud Server
|
|
66
|
-
// This must appear at the top of the app.js file (ahead of config) for things to work
|
|
67
|
-
//
|
|
68
|
-
////////////////////////////////////////////////////////////////////////////
|
|
69
|
-
|
|
70
|
-
// NOTE: changeOrigin must be true because of the way that we set host to host:port
|
|
71
|
-
// in http-proxy's common.js line 102, the host is only properly set up if changeOrigin is set to true
|
|
72
|
-
// this sets the "host" header and it has to match what is set at the network/transport level in a way
|
|
73
|
-
// (inner workings of Node http request)
|
|
74
|
-
//
|
|
75
|
-
var proxyConfig = {
|
|
76
|
-
"target": proxyTarget,
|
|
77
|
-
"agent": http.globalAgent,
|
|
78
|
-
"xfwd": false,
|
|
79
|
-
"proxyTimeout": process.defaultHttpTimeoutMs,
|
|
80
|
-
"changeOrigin": true
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// use https?
|
|
84
|
-
if (util.isHttps(proxyTarget))
|
|
85
|
-
{
|
|
86
|
-
// parse the target to get host
|
|
87
|
-
var proxyHost = urlTool.parse(proxyTarget).host;
|
|
88
|
-
|
|
89
|
-
proxyConfig = {
|
|
90
|
-
"target": proxyTarget,
|
|
91
|
-
"agent": https.globalAgent,
|
|
92
|
-
"headers": {
|
|
93
|
-
"host": proxyHost
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
66
|
|
|
98
|
-
// create proxy server instance
|
|
99
|
-
var proxyServer = new httpProxy.createProxyServer(proxyConfig);
|
|
100
67
|
|
|
101
|
-
// error handling
|
|
102
|
-
proxyServer.on("error", function(err, req, res) {
|
|
103
|
-
process.log(err);
|
|
104
|
-
res.writeHead(500, {
|
|
105
|
-
'Content-Type': 'text/plain'
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
res.end('Something went wrong while proxying the request.');
|
|
109
|
-
});
|
|
110
68
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
69
|
+
var createProxyHandler = function(proxyTarget, pathPrefix)
|
|
70
|
+
{
|
|
71
|
+
const proxy = require("http2-proxy");
|
|
72
|
+
const finalhandler = require('finalhandler')
|
|
73
|
+
|
|
74
|
+
const defaultWebHandler = function(err, req, res) {
|
|
75
|
+
if (err)
|
|
117
76
|
{
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// add received chunk to chunks array
|
|
122
|
-
chunks.push(chunk);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
proxyRes.on("end", function () {
|
|
126
|
-
|
|
127
|
-
if (proxyRes.statusCode === 401)
|
|
128
|
-
{
|
|
129
|
-
var text = "" + Buffer.concat(chunks);
|
|
130
|
-
if (text && (text.indexOf("invalid_token") > -1) || (text.indexOf("invalid_grant") > -1))
|
|
131
|
-
{
|
|
132
|
-
var identifier = req.identity_properties.provider_id + "/" + req.identity_properties.user_identifier;
|
|
133
|
-
|
|
134
|
-
_LOCK([identifier], function(releaseLockFn) {
|
|
135
|
-
|
|
136
|
-
var cleanup = function (full)
|
|
137
|
-
{
|
|
138
|
-
delete Gitana.APPS[req.identity_properties.token];
|
|
139
|
-
delete Gitana.PLATFORM_CACHE[req.identity_properties.token];
|
|
140
|
-
|
|
141
|
-
if (full) {
|
|
142
|
-
auth.removeUserCacheEntry(identifier);
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
// null out the access token
|
|
147
|
-
// this will force the refresh token to be used to get a new one on the next request
|
|
148
|
-
req.gitana_user.getDriver().http.refresh(function (err) {
|
|
149
|
-
|
|
150
|
-
if (err) {
|
|
151
|
-
cleanup(true);
|
|
152
|
-
req.log("Invalidated auth state for gitana user: " + req.identity_properties.token);
|
|
153
|
-
releaseLockFn();
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
req.gitana_user.getDriver().reloadAuthInfo(function () {
|
|
158
|
-
cleanup(true);
|
|
159
|
-
req.log("Refreshed token for gitana user: " + req.identity_properties.token);
|
|
160
|
-
releaseLockFn();
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
});
|
|
77
|
+
console.log("A web proxy error was caught, path: " + req.path + ", err: ", err);
|
|
78
|
+
try { res.status(500); } catch (e) { }
|
|
79
|
+
try { res.end('Something went wrong while proxying the request.'); } catch (e) { }
|
|
168
80
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
81
|
+
|
|
82
|
+
finalhandler(req, res)(err);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// const defaultWsHandler = function(err, req, socket, head) {
|
|
86
|
+
// if (err) {
|
|
87
|
+
// console.error('proxy error (ws)', err);
|
|
88
|
+
// socket.destroy();
|
|
89
|
+
// }
|
|
90
|
+
// };
|
|
91
|
+
|
|
92
|
+
//console.log("Proxy Target: " + proxyTarget);
|
|
93
|
+
|
|
94
|
+
var hostname = urlTool.parse(proxyTarget).hostname;
|
|
95
|
+
var port = urlTool.parse(proxyTarget).port;
|
|
96
|
+
var protocol = urlTool.parse(proxyTarget).protocol;
|
|
97
|
+
|
|
98
|
+
// web
|
|
99
|
+
var webConfig = {};
|
|
100
|
+
webConfig.hostname = hostname;
|
|
101
|
+
webConfig.port = port;
|
|
102
|
+
webConfig.protocol = protocol;
|
|
103
|
+
//webConfig.path = null;
|
|
104
|
+
webConfig.proxyTimeout = 120000;
|
|
105
|
+
webConfig.proxyName = "Cloud CMS UI Proxy";
|
|
106
|
+
webConfig.onReq = function(req, options) {
|
|
107
|
+
|
|
108
|
+
if (!options.headers) {
|
|
109
|
+
options.headers = {};
|
|
110
|
+
}
|
|
111
|
+
var headers = options.headers;
|
|
172
112
|
|
|
113
|
+
if (options.path && options.path.startsWith("/proxy")) {
|
|
114
|
+
options.path = options.path.substring(6);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (pathPrefix) {
|
|
118
|
+
options.path = path.join(pathPrefix, options.path);
|
|
119
|
+
}
|
|
120
|
+
|
|
173
121
|
// used to auto-assign the client header for /oauth/token requests
|
|
174
122
|
oauth2.autoProxy(req);
|
|
175
|
-
|
|
123
|
+
|
|
176
124
|
// copy domain host into "x-cloudcms-domainhost"
|
|
177
|
-
if (req.domainHost)
|
|
178
|
-
|
|
179
|
-
req.headers["x-cloudcms-domainhost"] = req.domainHost; // this could be "localhost"
|
|
125
|
+
if (req.domainHost) {
|
|
126
|
+
headers["x-cloudcms-domainhost"] = req.domainHost; // this could be "localhost"
|
|
180
127
|
}
|
|
181
|
-
|
|
128
|
+
|
|
182
129
|
// copy virtual host into "x-cloudcms-virtualhost"
|
|
183
|
-
if (req.virtualHost)
|
|
184
|
-
|
|
185
|
-
req.headers["x-cloudcms-virtualhost"] = req.virtualHost; // this could be "root.cloudcms.net" or "abc.cloudcms.net"
|
|
130
|
+
if (req.virtualHost) {
|
|
131
|
+
headers["x-cloudcms-virtualhost"] = req.virtualHost; // this could be "root.cloudcms.net" or "abc.cloudcms.net"
|
|
186
132
|
}
|
|
187
|
-
|
|
133
|
+
|
|
188
134
|
// copy deployment descriptor info
|
|
189
135
|
if (req.descriptor)
|
|
190
136
|
{
|
|
@@ -192,29 +138,29 @@ var createProxyHandler = function(proxyTarget, pathPrefix)
|
|
|
192
138
|
{
|
|
193
139
|
if (req.descriptor.tenant.id)
|
|
194
140
|
{
|
|
195
|
-
|
|
141
|
+
headers["x-cloudcms-tenant-id"] = req.descriptor.tenant.id;
|
|
196
142
|
}
|
|
197
|
-
|
|
143
|
+
|
|
198
144
|
if (req.descriptor.tenant.title)
|
|
199
145
|
{
|
|
200
|
-
|
|
146
|
+
headers["x-cloudcms-tenant-title"] = req.descriptor.tenant.title;
|
|
201
147
|
}
|
|
202
148
|
}
|
|
203
|
-
|
|
149
|
+
|
|
204
150
|
if (req.descriptor.application)
|
|
205
151
|
{
|
|
206
152
|
if (req.descriptor.application.id)
|
|
207
153
|
{
|
|
208
|
-
|
|
154
|
+
headers["x-cloudcms-application-id"] = req.descriptor.application.id;
|
|
209
155
|
}
|
|
210
|
-
|
|
156
|
+
|
|
211
157
|
if (req.descriptor.application.title)
|
|
212
158
|
{
|
|
213
|
-
|
|
159
|
+
headers["x-cloudcms-application-title"] = req.descriptor.application.title;
|
|
214
160
|
}
|
|
215
161
|
}
|
|
216
162
|
}
|
|
217
|
-
|
|
163
|
+
|
|
218
164
|
// set optional "x-cloudcms-origin" header
|
|
219
165
|
var cloudcmsOrigin = null;
|
|
220
166
|
if (req.virtualHost)
|
|
@@ -223,155 +169,179 @@ var createProxyHandler = function(proxyTarget, pathPrefix)
|
|
|
223
169
|
}
|
|
224
170
|
if (cloudcmsOrigin)
|
|
225
171
|
{
|
|
226
|
-
|
|
172
|
+
headers["x-cloudcms-origin"] = cloudcmsOrigin;
|
|
227
173
|
}
|
|
228
|
-
|
|
174
|
+
|
|
229
175
|
// set x-cloudcms-server-version header
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
//
|
|
233
|
-
//
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
//
|
|
237
|
-
|
|
238
|
-
//
|
|
239
|
-
// our algorithm here is pretty weak but suffices for the moment.
|
|
240
|
-
// if the req.headers["x-forwarded-host"] first entry is in the req.headers["referer"] then we consider
|
|
241
|
-
// things to have been CNAME forwarded
|
|
242
|
-
// and so we write cookies back to the req.headers["x-forwarded-host"] first entry domain
|
|
243
|
-
/*
|
|
244
|
-
var xForwardedHost = req.headers["x-forwarded-host"];
|
|
245
|
-
if (xForwardedHost)
|
|
176
|
+
headers["x-cloudcms-server-version"] = process.env.CLOUDCMS_APPSERVER_PACKAGE_VERSION;
|
|
177
|
+
|
|
178
|
+
// keep alive
|
|
179
|
+
//req.headers["connection"] = "keep-alive";
|
|
180
|
+
|
|
181
|
+
// if the incoming request didn't have an "Authorization" header
|
|
182
|
+
// and we have a logged in Gitana User via Auth, then set authorization header to Bearer Access Token
|
|
183
|
+
if (!req.headers["authorization"])
|
|
246
184
|
{
|
|
247
|
-
|
|
248
|
-
if (xForwardedHost.length > 0)
|
|
185
|
+
if (req.gitana_user)
|
|
249
186
|
{
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
var referer = req.headers["referer"];
|
|
253
|
-
if (referer && referer.indexOf("://" + cnameCandidate) > -1)
|
|
254
|
-
{
|
|
255
|
-
req.log("Detected CNAME: " + cnameCandidate);
|
|
256
|
-
|
|
257
|
-
proxyHostHeader = cnameCandidate;
|
|
258
|
-
}
|
|
187
|
+
headers["authorization"] = "Bearer " + req.gitana_user.getDriver().http.accessToken();
|
|
259
188
|
}
|
|
260
|
-
|
|
261
|
-
*/
|
|
262
|
-
|
|
263
|
-
// we fall back to using http-node-proxy's xfwd support
|
|
264
|
-
// thus, spoof header here on request so that "x-forwarded-host" is set properly
|
|
265
|
-
//req.headers["host"] = proxyHostHeader;
|
|
266
|
-
|
|
267
|
-
// keep alive
|
|
268
|
-
req.headers["connection"] = "keep-alive";
|
|
269
|
-
|
|
270
|
-
// allow forced cookie domains
|
|
271
|
-
var forcedCookieDomain = req.headers["cloudcmscookiedomain"];
|
|
272
|
-
if (!forcedCookieDomain)
|
|
273
|
-
{
|
|
274
|
-
if (process.env.CLOUDCMS_FORCE_COOKIE_DOMAIN)
|
|
189
|
+
else if (req.gitana_proxy_access_token)
|
|
275
190
|
{
|
|
276
|
-
|
|
191
|
+
headers["authorization"] = "Bearer " + req.gitana_proxy_access_token;
|
|
277
192
|
}
|
|
278
193
|
}
|
|
279
|
-
|
|
194
|
+
};
|
|
195
|
+
webConfig.onRes = function(req, res, proxyRes) {
|
|
196
|
+
|
|
197
|
+
if (req.gitana_user)
|
|
280
198
|
{
|
|
281
|
-
|
|
282
|
-
|
|
199
|
+
var chunks = [];
|
|
200
|
+
|
|
201
|
+
// triggers on data receive
|
|
202
|
+
proxyRes.on('data', function(chunk) {
|
|
203
|
+
// add received chunk to chunks array
|
|
204
|
+
chunks.push(chunk);
|
|
205
|
+
});
|
|
283
206
|
|
|
284
|
-
|
|
285
|
-
{
|
|
286
|
-
// replace the domain with the host
|
|
287
|
-
var i = value.toLowerCase().indexOf("domain=");
|
|
288
|
-
if (i > -1)
|
|
289
|
-
{
|
|
290
|
-
var j = value.indexOf(";", i);
|
|
291
|
-
if (j === -1)
|
|
292
|
-
{
|
|
293
|
-
value = value.substring(0, i);
|
|
294
|
-
}
|
|
295
|
-
else
|
|
296
|
-
{
|
|
297
|
-
value = value.substring(0, i) + value.substring(j);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
207
|
+
proxyRes.on("end", function () {
|
|
300
208
|
|
|
301
|
-
|
|
302
|
-
if (!util.isSecure(req))
|
|
303
|
-
{
|
|
304
|
-
var i = value.toLowerCase().indexOf("; secure");
|
|
305
|
-
if (i > -1)
|
|
209
|
+
if (proxyRes.statusCode === 401)
|
|
306
210
|
{
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
211
|
+
var text = "" + Buffer.concat(chunks);
|
|
212
|
+
if (text && (text.indexOf("invalid_token") > -1) || (text.indexOf("invalid_grant") > -1))
|
|
213
|
+
{
|
|
214
|
+
var identifier = req.identity_properties.provider_id + "/" + req.identity_properties.user_identifier;
|
|
310
215
|
|
|
311
|
-
|
|
312
|
-
if (util.isSecure(req))
|
|
313
|
-
{
|
|
314
|
-
var i = value.toLowerCase().indexOf("; secure");
|
|
315
|
-
var j = value.toLowerCase().indexOf(";secure");
|
|
316
|
-
if (i === -1 && j === -1)
|
|
317
|
-
{
|
|
318
|
-
value += ";secure";
|
|
319
|
-
}
|
|
320
|
-
}
|
|
216
|
+
_LOCK([identifier], function(err, releaseLockFn) {
|
|
321
217
|
|
|
322
|
-
|
|
323
|
-
|
|
218
|
+
if (err)
|
|
219
|
+
{
|
|
220
|
+
// failed to acquire lock
|
|
221
|
+
console.log("FAILED TO ACQUIRE LOCK", err);
|
|
222
|
+
req.log("FAILED TO ACQUIRE LOCK", err);
|
|
223
|
+
try { releaseLockFn(); } catch (e) { }
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
324
226
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
res.setHeader = function(key, value)
|
|
330
|
-
{
|
|
331
|
-
var _key = key.toLowerCase();
|
|
227
|
+
var cleanup = function (full)
|
|
228
|
+
{
|
|
229
|
+
delete Gitana.APPS[req.identity_properties.token];
|
|
230
|
+
delete Gitana.PLATFORM_CACHE[req.identity_properties.token];
|
|
332
231
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
else
|
|
338
|
-
{
|
|
339
|
-
if (_key === "set-cookie")
|
|
340
|
-
{
|
|
341
|
-
for (var x in value)
|
|
342
|
-
{
|
|
343
|
-
value[x] = updateSetCookieValue(value[x]);
|
|
344
|
-
}
|
|
345
|
-
}
|
|
232
|
+
if (full) {
|
|
233
|
+
auth.removeUserCacheEntry(identifier);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
346
236
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
_setHeader.call(this, key, value);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
};
|
|
237
|
+
// null out the access token
|
|
238
|
+
// this will force the refresh token to be used to get a new one on the next request
|
|
239
|
+
req.gitana_user.getDriver().http.refresh(function (err) {
|
|
354
240
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
{
|
|
361
|
-
req.headers["authorization"] = "Bearer " + req.gitana_user.getDriver().http.accessToken();
|
|
362
|
-
}
|
|
363
|
-
else if (req.gitana_proxy_access_token)
|
|
364
|
-
{
|
|
365
|
-
req.headers["authorization"] = "Bearer " + req.gitana_proxy_access_token;
|
|
366
|
-
}
|
|
367
|
-
}
|
|
241
|
+
if (err) {
|
|
242
|
+
cleanup(true);
|
|
243
|
+
req.log("Invalidated auth state for gitana user: " + req.identity_properties.token);
|
|
244
|
+
return releaseLockFn();
|
|
245
|
+
}
|
|
368
246
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
247
|
+
req.gitana_user.getDriver().reloadAuthInfo(function () {
|
|
248
|
+
cleanup(true);
|
|
249
|
+
req.log("Refreshed token for gitana user: " + req.identity_properties.token);
|
|
250
|
+
releaseLockFn();
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
}
|
|
372
255
|
|
|
373
|
-
|
|
374
|
-
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
//res.setHeader('x-powered-by', 'cloudcms');
|
|
261
|
+
res.writeHead(proxyRes.statusCode, proxyRes.headers)
|
|
262
|
+
proxyRes.pipe(res)
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
var proxyRequestHandler = function(req, res) {
|
|
266
|
+
proxy.web(req, res, webConfig, function(err, req, res) {
|
|
267
|
+
defaultWebHandler(err, req, res);
|
|
268
|
+
});
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
// cookie domain rewrite?
|
|
273
|
+
|
|
274
|
+
// // if we're using auth credentials that are picked up in SSO chain, then we listen for a 401
|
|
275
|
+
// // and if we hear it, we automatically invalidate the SSO chain so that the next request
|
|
276
|
+
// // will continue to work
|
|
277
|
+
// proxyServer.on("proxyRes", function (proxyRes, req, res) {
|
|
278
|
+
//
|
|
279
|
+
// console.log("proxyRes.1");
|
|
280
|
+
//
|
|
281
|
+
// if (req.gitana_user)
|
|
282
|
+
// {
|
|
283
|
+
// var chunks = [];
|
|
284
|
+
// // triggers on data receive
|
|
285
|
+
// proxyRes.on('data', function(chunk) {
|
|
286
|
+
// // add received chunk to chunks array
|
|
287
|
+
// chunks.push(chunk);
|
|
288
|
+
// });
|
|
289
|
+
//
|
|
290
|
+
// proxyRes.on("end", function () {
|
|
291
|
+
//
|
|
292
|
+
// console.log("proxyRes.end, code: " + proxyRes.statusCode);
|
|
293
|
+
//
|
|
294
|
+
// if (proxyRes.statusCode === 401)
|
|
295
|
+
// {
|
|
296
|
+
// var text = "" + Buffer.concat(chunks);
|
|
297
|
+
// if (text && (text.indexOf("invalid_token") > -1) || (text.indexOf("invalid_grant") > -1))
|
|
298
|
+
// {
|
|
299
|
+
// var identifier = req.identity_properties.provider_id + "/" + req.identity_properties.user_identifier;
|
|
300
|
+
//
|
|
301
|
+
// _LOCK([identifier], function(err, releaseLockFn) {
|
|
302
|
+
//
|
|
303
|
+
// if (err)
|
|
304
|
+
// {
|
|
305
|
+
// // failed to acquire lock
|
|
306
|
+
// console.log("FAILED TO ACQUIRE LOCK", err);
|
|
307
|
+
// req.log("FAILED TO ACQUIRE LOCK", err);
|
|
308
|
+
// return;
|
|
309
|
+
// }
|
|
310
|
+
//
|
|
311
|
+
// var cleanup = function (full)
|
|
312
|
+
// {
|
|
313
|
+
// delete Gitana.APPS[req.identity_properties.token];
|
|
314
|
+
// delete Gitana.PLATFORM_CACHE[req.identity_properties.token];
|
|
315
|
+
//
|
|
316
|
+
// if (full) {
|
|
317
|
+
// auth.removeUserCacheEntry(identifier);
|
|
318
|
+
// }
|
|
319
|
+
// };
|
|
320
|
+
//
|
|
321
|
+
// // null out the access token
|
|
322
|
+
// // this will force the refresh token to be used to get a new one on the next request
|
|
323
|
+
// req.gitana_user.getDriver().http.refresh(function (err) {
|
|
324
|
+
//
|
|
325
|
+
// if (err) {
|
|
326
|
+
// cleanup(true);
|
|
327
|
+
// req.log("Invalidated auth state for gitana user: " + req.identity_properties.token);
|
|
328
|
+
// releaseLockFn();
|
|
329
|
+
// return;
|
|
330
|
+
// }
|
|
331
|
+
//
|
|
332
|
+
// req.gitana_user.getDriver().reloadAuthInfo(function () {
|
|
333
|
+
// cleanup(true);
|
|
334
|
+
// req.log("Refreshed token for gitana user: " + req.identity_properties.token);
|
|
335
|
+
// releaseLockFn();
|
|
336
|
+
// });
|
|
337
|
+
// });
|
|
338
|
+
// });
|
|
339
|
+
// }
|
|
340
|
+
//
|
|
341
|
+
// }
|
|
342
|
+
// });
|
|
343
|
+
// }
|
|
344
|
+
// });
|
|
375
345
|
|
|
376
|
-
return
|
|
346
|
+
return proxyRequestHandler;
|
|
377
347
|
};
|