cloudcms-server 4.0.0-beta.6 → 4.0.0-beta.8
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/cloudcms-server.iml +1 -0
- package/middleware/awareness/plugins/editorial.js +3 -2
- package/middleware/driver-config/driver-config.js +0 -6
- package/middleware/modules/modules.js +11 -5
- package/middleware/stores/store.js +0 -1
- package/middleware/stores/stores.js +1 -1
- package/middleware/virtual-config/virtual-config.js +0 -3
- package/middleware/virtual-files/virtual-files.js +0 -3
- package/middleware/welcome/welcome.js +0 -3
- package/notifications/providers/kafka.js +182 -0
- package/notifications/providers/stomp.js +4 -0
- package/package.json +9 -10
- package/server/index.js +4 -1
- package/util/proxy-factory.js +143 -168
package/cloudcms-server.iml
CHANGED
|
@@ -231,10 +231,11 @@ exports.bindSocket = function(socket, provider, io)
|
|
|
231
231
|
var x1 = cookieValue.indexOf("GITANA_TICKET=");
|
|
232
232
|
if (x1 > -1)
|
|
233
233
|
{
|
|
234
|
-
|
|
234
|
+
ticket = cookieValue.substring(x1 + 14);
|
|
235
|
+
var x2 = ticket.indexOf(";");
|
|
235
236
|
if (x2 > -1)
|
|
236
237
|
{
|
|
237
|
-
ticket =
|
|
238
|
+
ticket = ticket.substring(0, x2);
|
|
238
239
|
}
|
|
239
240
|
}
|
|
240
241
|
}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
var path = require('path');
|
|
2
|
-
var http = require('http');
|
|
3
|
-
var request = require('request');
|
|
4
1
|
var util = require("../../util/util");
|
|
5
|
-
var Gitana = require("gitana");
|
|
6
|
-
|
|
7
|
-
var fs = require("fs");
|
|
8
2
|
|
|
9
3
|
/**
|
|
10
4
|
* Retrieves local driver configuration for hosts from Cloud CMS.
|
|
@@ -55,14 +55,20 @@ exports = module.exports = function()
|
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
var source = moduleConfig.source40;
|
|
59
|
+
if (!source)
|
|
60
|
+
{
|
|
61
|
+
source = moduleConfig.source;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!source)
|
|
59
65
|
{
|
|
60
66
|
return callback({
|
|
61
67
|
"message": "Missing module config source settings"
|
|
62
68
|
});
|
|
63
69
|
}
|
|
64
70
|
|
|
65
|
-
var sourceType =
|
|
71
|
+
var sourceType = source.type;
|
|
66
72
|
if (!sourceType)
|
|
67
73
|
{
|
|
68
74
|
return callback({
|
|
@@ -70,7 +76,7 @@ exports = module.exports = function()
|
|
|
70
76
|
});
|
|
71
77
|
}
|
|
72
78
|
|
|
73
|
-
var sourceUrl =
|
|
79
|
+
var sourceUrl = source.uri;
|
|
74
80
|
if (!sourceUrl)
|
|
75
81
|
{
|
|
76
82
|
return callback({
|
|
@@ -78,12 +84,12 @@ exports = module.exports = function()
|
|
|
78
84
|
});
|
|
79
85
|
}
|
|
80
86
|
|
|
81
|
-
var sourcePath =
|
|
87
|
+
var sourcePath = source.path;
|
|
82
88
|
if (!sourcePath) {
|
|
83
89
|
sourcePath = "/";
|
|
84
90
|
}
|
|
85
91
|
|
|
86
|
-
var sourceBranch =
|
|
92
|
+
var sourceBranch = source.branch;
|
|
87
93
|
if (!sourceBranch) {
|
|
88
94
|
sourceBranch = "master";
|
|
89
95
|
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
const { Kafka } = require("kafkajs");
|
|
2
|
+
const util = require("../../util/util");
|
|
3
|
+
|
|
4
|
+
var holder = {};
|
|
5
|
+
|
|
6
|
+
module.exports = {};
|
|
7
|
+
module.exports.start = function(configuration, callback)
|
|
8
|
+
{
|
|
9
|
+
// clientId
|
|
10
|
+
if (!configuration.clientId)
|
|
11
|
+
{
|
|
12
|
+
if (process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_CLIENT_ID)
|
|
13
|
+
{
|
|
14
|
+
configuration.clientId = process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_CLIENT_ID;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (!configuration.clientId)
|
|
18
|
+
{
|
|
19
|
+
configuration.clientId = "cloudcms-ui-kafka-notifications-client";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// topic
|
|
23
|
+
if (!configuration.topic)
|
|
24
|
+
{
|
|
25
|
+
if (process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_TOPIC)
|
|
26
|
+
{
|
|
27
|
+
configuration.topic = process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_TOPIC;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (!configuration.topic)
|
|
31
|
+
{
|
|
32
|
+
configuration.topic = "cloudcms.ui.topic";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// group
|
|
36
|
+
if (!configuration.group)
|
|
37
|
+
{
|
|
38
|
+
if (process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_GROUP)
|
|
39
|
+
{
|
|
40
|
+
configuration.group = process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_GROUP;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (!configuration.group) {
|
|
44
|
+
configuration.group = "cloudcms-ui-kafka-notifications-group";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// brokers
|
|
48
|
+
if (!configuration.brokers)
|
|
49
|
+
{
|
|
50
|
+
if (process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_BROKERS)
|
|
51
|
+
{
|
|
52
|
+
configuration.brokers = process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_BROKERS;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
var clientId = configuration.clientId;
|
|
57
|
+
var brokers = configuration.brokers.split(",");
|
|
58
|
+
var topic = configuration.topic;
|
|
59
|
+
var group = configuration.group;
|
|
60
|
+
|
|
61
|
+
process.log("Connecting to kafka, client ID: " + clientId + ", brokers: " + brokers + ", topic: " + topic + ", group: " + group);
|
|
62
|
+
|
|
63
|
+
if (holder.consumer)
|
|
64
|
+
{
|
|
65
|
+
return callback();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// console.log("a1");
|
|
69
|
+
var kafka = new Kafka({
|
|
70
|
+
clientId: clientId,
|
|
71
|
+
brokers: brokers
|
|
72
|
+
});
|
|
73
|
+
// console.log("a2: " + kafka);
|
|
74
|
+
// console.log("a3: " + kafka.consumer);
|
|
75
|
+
|
|
76
|
+
var consumer = holder.consumer = kafka.consumer({ groupId: group });
|
|
77
|
+
|
|
78
|
+
// connect
|
|
79
|
+
(async function() {
|
|
80
|
+
await consumer.connect()
|
|
81
|
+
}());
|
|
82
|
+
|
|
83
|
+
(async function() {
|
|
84
|
+
await consumer.subscribe({topic: topic, fromBeginning: true})
|
|
85
|
+
}());
|
|
86
|
+
|
|
87
|
+
callback();
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
module.exports.process = function(callback)
|
|
91
|
+
{
|
|
92
|
+
var consumer = holder.consumer;
|
|
93
|
+
if (!consumer)
|
|
94
|
+
{
|
|
95
|
+
return callback();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
(async function() {
|
|
99
|
+
await consumer.run({
|
|
100
|
+
eachMessage: async ({ topic, partition, message, heartbeat, pause }) => {
|
|
101
|
+
handleMessage(topic, partition, message, heartbeat, pause, callback);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}());
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
var handleMessage = function(topic, partition, messageObject, heartbeat, pause, callback)
|
|
108
|
+
{
|
|
109
|
+
// console.log("Topic: " + topic);
|
|
110
|
+
// console.log("Partition: " + partition);
|
|
111
|
+
// console.log("Message: " + JSON.stringify(messageObject, null, 2));
|
|
112
|
+
|
|
113
|
+
if (!messageObject || !messageObject.value)
|
|
114
|
+
{
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//var key = message.key.toString();
|
|
119
|
+
var valueString = messageObject.value.toString();
|
|
120
|
+
var headers = messageObject.headers || {};
|
|
121
|
+
|
|
122
|
+
var json = null;
|
|
123
|
+
if (valueString) {
|
|
124
|
+
json = JSON.parse("" + valueString);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// console.log("b1: " + valueString);
|
|
128
|
+
// console.log("b2: " + data);
|
|
129
|
+
|
|
130
|
+
if (json)
|
|
131
|
+
{
|
|
132
|
+
console.log("JSON: " + JSON.stringify(json));
|
|
133
|
+
console.log("HEADERS: " + JSON.stringify(headers));
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* kafka1-ui-1 | VAL: {"subject":"invalidate_objects:aea334cb8accb0bd698e","message":"","data":"{\"operation\":\"invalidate_objects\",\"invalidations\":[{\"applicationId\":\"1785c4b13f74b3aa4b31\",\"ref\":\"application://826a3ebefe4c1e006a60/1785c4b13f74b3aa4b31\",\"id\":\"1785c4b13f74b3aa4b31\",\"type\":\"application\",\"stackId\":\"a17879ca0923f6d9696b\",\"stackMembers\":{\"archives\":{\"typeId\":\"vault\",\"id\":\"385e37eb07bc3d16dca1\"},\"console\":{\"typeId\":\"application\",\"id\":\"1785c4b13f74b3aa4b31\"},\"content\":{\"typeId\":\"repository\",\"id\":\"9904550a6b2a2a71f015\"},\"hosting\":{\"typeId\":\"webhost\",\"id\":\"5d2db66ced26608dc355\"},\"oneteam\":{\"typeId\":\"application\",\"id\":\"8d5ba57420ce31a3172c\"},\"principals\":{\"typeId\":\"domain\",\"id\":\"32cbffafe9f2de4d1b9a\"},\"root\":{\"typeId\":\"directory\",\"id\":\"6db38348323d001c2c10\"}}}]}"}
|
|
137
|
+
* kafka1-ui-1 | HEADERS: [object Object]
|
|
138
|
+
* @type {*[]}
|
|
139
|
+
*/
|
|
140
|
+
|
|
141
|
+
var subject = json.subject;
|
|
142
|
+
var message = json.message;
|
|
143
|
+
|
|
144
|
+
// build out the notification message items
|
|
145
|
+
var items = [];
|
|
146
|
+
|
|
147
|
+
if (json.data)
|
|
148
|
+
{
|
|
149
|
+
var data = JSON.parse("" + json.data);
|
|
150
|
+
|
|
151
|
+
// timestamp from headers
|
|
152
|
+
//var timestamp = parseInt(headers.timestamp);
|
|
153
|
+
var timestamp = new Date().getTime();
|
|
154
|
+
|
|
155
|
+
// copy data as item
|
|
156
|
+
var item = util.clone(data, true);
|
|
157
|
+
if (!item)
|
|
158
|
+
{
|
|
159
|
+
item = {};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// other properties
|
|
163
|
+
item.timestamp = timestamp;
|
|
164
|
+
item.sentTimestamp = timestamp;
|
|
165
|
+
item.subject = subject;
|
|
166
|
+
|
|
167
|
+
// raw message
|
|
168
|
+
item.rawMessage = json.data; // string
|
|
169
|
+
|
|
170
|
+
items.push(item);
|
|
171
|
+
|
|
172
|
+
//console.log("ITEM: " + JSON.stringify(item));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// call back to notifications engine to process these items
|
|
177
|
+
// when they're done processing, our callback is fired so that we can handle deletes and things
|
|
178
|
+
// we call the done() method when we're finished
|
|
179
|
+
callback(null, items, function(err, items, done) {
|
|
180
|
+
done(err, items, items);
|
|
181
|
+
});
|
|
182
|
+
};
|
|
@@ -63,6 +63,7 @@ module.exports.start = function(configuration, callback)
|
|
|
63
63
|
var MessageConsumer = function MessageConsumer() { };
|
|
64
64
|
MessageConsumer.prototype.init = function init(done) {
|
|
65
65
|
console.log("STOMP client initializing to host: " + host + ", port: " + port);
|
|
66
|
+
var self = this;
|
|
66
67
|
var stompClient = new Stomp({
|
|
67
68
|
"host": host,
|
|
68
69
|
"port": port,
|
|
@@ -85,6 +86,9 @@ module.exports.start = function(configuration, callback)
|
|
|
85
86
|
});
|
|
86
87
|
|
|
87
88
|
done();
|
|
89
|
+
}, function(err) {
|
|
90
|
+
console.error("STOMP Error: " + err);
|
|
91
|
+
done(err);
|
|
88
92
|
});
|
|
89
93
|
};
|
|
90
94
|
holder.consumer = new MessageConsumer();
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
},
|
|
7
7
|
"name": "cloudcms-server",
|
|
8
8
|
"description": "Cloud CMS Application Server Module",
|
|
9
|
-
"version": "4.0.0-beta.
|
|
9
|
+
"version": "4.0.0-beta.8",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "git://github.com/gitana/cloudcms-server.git"
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
"@socket.io/redis-adapter": "^7.2.0",
|
|
17
17
|
"@socket.io/sticky": "^1.0.1",
|
|
18
18
|
"accepts": "^1.3.8",
|
|
19
|
-
"agentkeepalive": "^4.
|
|
19
|
+
"agentkeepalive": "^4.5.0",
|
|
20
20
|
"alpaca": "^1.5.27",
|
|
21
21
|
"archiver": "^5.1.0",
|
|
22
22
|
"async": "^3.2.3",
|
|
23
23
|
"async-lock": "^1.3.2",
|
|
24
24
|
"aws-sdk": "^2.1208.0",
|
|
25
|
-
"axios": "^
|
|
25
|
+
"axios": "^1.5.0",
|
|
26
26
|
"basic-auth": "^2.0.1",
|
|
27
27
|
"body-parser": "^1.20.0",
|
|
28
28
|
"bytes": "^3.1.0",
|
|
@@ -37,22 +37,21 @@
|
|
|
37
37
|
"dustjs-helpers": "^1.7.4",
|
|
38
38
|
"dustjs-linkedin": "^3.0.1",
|
|
39
39
|
"errorhandler": "^1.5.1",
|
|
40
|
-
"express": "^4.18.
|
|
40
|
+
"express": "^4.18.2",
|
|
41
41
|
"express-session": "^1.17.3",
|
|
42
42
|
"express-useragent": "^1.0.15",
|
|
43
43
|
"extend-with-super": "^2.0.0",
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"gitana": "^1.0.323",
|
|
44
|
+
"fast-proxy": "^2.2.0",
|
|
45
|
+
"gitana": "^1.0.324",
|
|
47
46
|
"handlebars": "^4.7.6",
|
|
48
47
|
"hbs": "^4.1.1",
|
|
49
48
|
"helmet": "^4.6.0",
|
|
50
|
-
"http2-proxy": "^5.0.53",
|
|
51
49
|
"ioredis": "4.28.5",
|
|
52
50
|
"json5": "^2.1.3",
|
|
53
|
-
"jsonwebtoken": "^
|
|
51
|
+
"jsonwebtoken": "^9.0.2",
|
|
52
|
+
"kafkajs": "^2.2.4",
|
|
54
53
|
"klaw": "^3.0.0",
|
|
55
|
-
"lru-cache": "^
|
|
54
|
+
"lru-cache": "^7.14.0",
|
|
56
55
|
"marked": "^4.0.14",
|
|
57
56
|
"memored": "^1.1.1",
|
|
58
57
|
"memorystore": "^1.6.4",
|
package/server/index.js
CHANGED
|
@@ -547,7 +547,6 @@ var runFunctions = function (functions, args, callback) {
|
|
|
547
547
|
* @param callback optional callback function
|
|
548
548
|
*/
|
|
549
549
|
exports.start = function(overrides, callback) {
|
|
550
|
-
|
|
551
550
|
setTimeout(function() {
|
|
552
551
|
_start(overrides, function(err) {
|
|
553
552
|
if (callback) {
|
|
@@ -780,6 +779,10 @@ var startServer = function(config, startServerFinishedFn)
|
|
|
780
779
|
|
|
781
780
|
// global service starts
|
|
782
781
|
main.init(app, function (err) {
|
|
782
|
+
|
|
783
|
+
if (err) {
|
|
784
|
+
return startServerFinishedFn(err);
|
|
785
|
+
}
|
|
783
786
|
|
|
784
787
|
app.enable('strict routing');
|
|
785
788
|
|
package/util/proxy-factory.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
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
|
|
11
|
-
|
|
12
|
-
var LRUCache = require("lru-cache");
|
|
10
|
+
var LRU = require("lru-cache");
|
|
13
11
|
|
|
14
12
|
var exports = module.exports;
|
|
15
13
|
|
|
@@ -19,9 +17,9 @@ var _LOCK = function(lockIdentifiers, workFunction)
|
|
|
19
17
|
process.locks.lock(name, workFunction);
|
|
20
18
|
};
|
|
21
19
|
|
|
22
|
-
var NAMED_PROXY_HANDLERS_CACHE = new
|
|
20
|
+
var NAMED_PROXY_HANDLERS_CACHE = new LRU({
|
|
23
21
|
max: 200,
|
|
24
|
-
|
|
22
|
+
ttl: 1000 * 60 * 60 // 60 minutes
|
|
25
23
|
});
|
|
26
24
|
|
|
27
25
|
var acquireProxyHandler = exports.acquireProxyHandler = function(proxyTarget, pathPrefix, callback)
|
|
@@ -35,36 +33,40 @@ var acquireProxyHandler = exports.acquireProxyHandler = function(proxyTarget, pa
|
|
|
35
33
|
{
|
|
36
34
|
return callback(null, _cachedHandler);
|
|
37
35
|
}
|
|
38
|
-
|
|
39
|
-
// take out a thread lock
|
|
40
|
-
_LOCK(["acquireProxyHandler", name], function(err, releaseLockFn) {
|
|
41
|
-
|
|
42
|
-
if (err)
|
|
43
|
-
{
|
|
44
|
-
console.log("Failed to acquire proxy handler: " + name + ", err: ", err);
|
|
45
|
-
|
|
46
|
-
// failed to acquire lock
|
|
47
|
-
return callback(err);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// second check to make sure another thread didn't create the handler in the meantime
|
|
51
|
-
_cachedHandler = NAMED_PROXY_HANDLERS_CACHE[name];
|
|
52
|
-
if (_cachedHandler)
|
|
53
|
-
{
|
|
54
|
-
releaseLockFn();
|
|
55
|
-
return callback(null, _cachedHandler);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// create the proxy handler and cache it into LRU cache
|
|
59
|
-
//console.log("Acquiring proxy handler: " + name + ", for target: " + proxyTarget + " and prefix: " + pathPrefix);
|
|
60
|
-
_cachedHandler = createProxyHandler(proxyTarget, pathPrefix);
|
|
61
|
-
|
|
62
|
-
// store back into LRU cache
|
|
63
|
-
NAMED_PROXY_HANDLERS_CACHE[name] = _cachedHandler;
|
|
64
36
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
37
|
+
// // take out a thread lock
|
|
38
|
+
// _LOCK(["acquireProxyHandler", name], function(err, releaseLockFn) {
|
|
39
|
+
//
|
|
40
|
+
// if (err)
|
|
41
|
+
// {
|
|
42
|
+
// console.log("Failed to acquire proxy handler: " + name + ", err: ", err);
|
|
43
|
+
//
|
|
44
|
+
// // failed to acquire lock
|
|
45
|
+
// return callback(err);
|
|
46
|
+
// }
|
|
47
|
+
//
|
|
48
|
+
// // second check to make sure another thread didn't create the handler in the meantime
|
|
49
|
+
// _cachedHandler = NAMED_PROXY_HANDLERS_CACHE[name];
|
|
50
|
+
// if (_cachedHandler)
|
|
51
|
+
// {
|
|
52
|
+
// releaseLockFn();
|
|
53
|
+
// return callback(null, _cachedHandler);
|
|
54
|
+
// }
|
|
55
|
+
//
|
|
56
|
+
// // create the proxy handler and cache it into LRU cache
|
|
57
|
+
// //console.log("Acquiring proxy handler: " + name + ", for target: " + proxyTarget + " and prefix: " + pathPrefix);
|
|
58
|
+
// _cachedHandler = createProxyHandler(proxyTarget, pathPrefix);
|
|
59
|
+
//
|
|
60
|
+
// // store back into LRU cache
|
|
61
|
+
// NAMED_PROXY_HANDLERS_CACHE[name] = _cachedHandler;
|
|
62
|
+
//
|
|
63
|
+
// releaseLockFn();
|
|
64
|
+
// callback(null, _cachedHandler);
|
|
65
|
+
// });
|
|
66
|
+
|
|
67
|
+
_cachedHandler = NAMED_PROXY_HANDLERS_CACHE[name] = createProxyHandler(proxyTarget, pathPrefix);
|
|
68
|
+
|
|
69
|
+
callback(null, _cachedHandler);
|
|
68
70
|
};
|
|
69
71
|
|
|
70
72
|
|
|
@@ -72,70 +74,106 @@ var acquireProxyHandler = exports.acquireProxyHandler = function(proxyTarget, pa
|
|
|
72
74
|
|
|
73
75
|
var createProxyHandler = function(proxyTarget, pathPrefix)
|
|
74
76
|
{
|
|
75
|
-
const proxy = require(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
const { proxy, close } = require('fast-proxy')({
|
|
78
|
+
base: proxyTarget,
|
|
79
|
+
cacheURLs: 0,
|
|
80
|
+
//http2: true,
|
|
81
|
+
//undici: true
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
var proxyOptions = {};
|
|
85
|
+
proxyOptions.onResponse = function(req, res, stream) {
|
|
86
|
+
|
|
87
|
+
if (req.gitana_user)
|
|
80
88
|
{
|
|
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
|
-
|
|
89
|
+
var chunks = [];
|
|
90
|
+
|
|
91
|
+
// triggers on data receive
|
|
92
|
+
stream.on('data', function(chunk) {
|
|
93
|
+
console.log("DATA!");
|
|
94
|
+
// add received chunk to chunks array
|
|
95
|
+
chunks.push(chunk);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
stream.on("end", function () {
|
|
99
|
+
|
|
100
|
+
if (stream.statusCode === 401)
|
|
101
|
+
{
|
|
102
|
+
var text = "" + Buffer.concat(chunks);
|
|
103
|
+
if (text && (text.indexOf("invalid_token") > -1) || (text.indexOf("invalid_grant") > -1))
|
|
104
|
+
{
|
|
105
|
+
var identifier = req.identity_properties.provider_id + "/" + req.identity_properties.user_identifier;
|
|
106
|
+
|
|
107
|
+
_LOCK([identifier], function(err, releaseLockFn) {
|
|
108
|
+
|
|
109
|
+
if (err)
|
|
110
|
+
{
|
|
111
|
+
// failed to acquire lock
|
|
112
|
+
console.log("FAILED TO ACQUIRE LOCK", err);
|
|
113
|
+
req.log("FAILED TO ACQUIRE LOCK", err);
|
|
114
|
+
try { releaseLockFn(); } catch (e) { }
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
var cleanup = function (full)
|
|
119
|
+
{
|
|
120
|
+
delete Gitana.APPS[req.identity_properties.token];
|
|
121
|
+
delete Gitana.PLATFORM_CACHE[req.identity_properties.token];
|
|
122
|
+
|
|
123
|
+
if (full) {
|
|
124
|
+
auth.removeUserCacheEntry(identifier);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// null out the access token
|
|
129
|
+
// this will force the refresh token to be used to get a new one on the next request
|
|
130
|
+
req.gitana_user.getDriver().http.refresh(function (err) {
|
|
131
|
+
|
|
132
|
+
if (err) {
|
|
133
|
+
cleanup(true);
|
|
134
|
+
req.log("Invalidated auth state for gitana user: " + req.identity_properties.token);
|
|
135
|
+
return releaseLockFn();
|
|
136
|
+
}
|
|
117
137
|
|
|
118
|
-
|
|
119
|
-
|
|
138
|
+
req.gitana_user.getDriver().reloadAuthInfo(function () {
|
|
139
|
+
cleanup(true);
|
|
140
|
+
req.log("Refreshed token for gitana user: " + req.identity_properties.token);
|
|
141
|
+
releaseLockFn();
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
});
|
|
120
149
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
150
|
+
|
|
151
|
+
//res.setHeader('x-powered-by', 'cloudcms');
|
|
152
|
+
if (stream.statusCode && stream.headers) {
|
|
153
|
+
res.writeHead(stream.statusCode, stream.headers)
|
|
124
154
|
}
|
|
125
|
-
|
|
155
|
+
|
|
156
|
+
stream.pipe(res)
|
|
157
|
+
};
|
|
158
|
+
proxyOptions.rewriteRequestHeaders = function(req, headers)
|
|
159
|
+
{
|
|
126
160
|
// used to auto-assign the client header for /oauth/token requests
|
|
127
161
|
oauth2.autoProxy(req);
|
|
128
|
-
|
|
162
|
+
if (req.headers && req.headers.authorization)
|
|
163
|
+
{
|
|
164
|
+
headers["authorization"] = req.headers.authorization;
|
|
165
|
+
}
|
|
166
|
+
|
|
129
167
|
// copy domain host into "x-cloudcms-domainhost"
|
|
130
168
|
if (req.domainHost) {
|
|
131
169
|
headers["x-cloudcms-domainhost"] = req.domainHost; // this could be "localhost"
|
|
132
170
|
}
|
|
133
|
-
|
|
171
|
+
|
|
134
172
|
// copy virtual host into "x-cloudcms-virtualhost"
|
|
135
173
|
if (req.virtualHost) {
|
|
136
174
|
headers["x-cloudcms-virtualhost"] = req.virtualHost; // this could be "root.cloudcms.net" or "abc.cloudcms.net"
|
|
137
175
|
}
|
|
138
|
-
|
|
176
|
+
|
|
139
177
|
// copy deployment descriptor info
|
|
140
178
|
if (req.descriptor)
|
|
141
179
|
{
|
|
@@ -145,27 +183,27 @@ var createProxyHandler = function(proxyTarget, pathPrefix)
|
|
|
145
183
|
{
|
|
146
184
|
headers["x-cloudcms-tenant-id"] = req.descriptor.tenant.id;
|
|
147
185
|
}
|
|
148
|
-
|
|
186
|
+
|
|
149
187
|
if (req.descriptor.tenant.title)
|
|
150
188
|
{
|
|
151
189
|
headers["x-cloudcms-tenant-title"] = req.descriptor.tenant.title;
|
|
152
190
|
}
|
|
153
191
|
}
|
|
154
|
-
|
|
192
|
+
|
|
155
193
|
if (req.descriptor.application)
|
|
156
194
|
{
|
|
157
195
|
if (req.descriptor.application.id)
|
|
158
196
|
{
|
|
159
197
|
headers["x-cloudcms-application-id"] = req.descriptor.application.id;
|
|
160
198
|
}
|
|
161
|
-
|
|
199
|
+
|
|
162
200
|
if (req.descriptor.application.title)
|
|
163
201
|
{
|
|
164
202
|
headers["x-cloudcms-application-title"] = req.descriptor.application.title;
|
|
165
203
|
}
|
|
166
204
|
}
|
|
167
205
|
}
|
|
168
|
-
|
|
206
|
+
|
|
169
207
|
// set optional "x-cloudcms-origin" header
|
|
170
208
|
var cloudcmsOrigin = null;
|
|
171
209
|
if (req.virtualHost)
|
|
@@ -176,13 +214,13 @@ var createProxyHandler = function(proxyTarget, pathPrefix)
|
|
|
176
214
|
{
|
|
177
215
|
headers["x-cloudcms-origin"] = cloudcmsOrigin;
|
|
178
216
|
}
|
|
179
|
-
|
|
217
|
+
|
|
180
218
|
// set x-cloudcms-server-version header
|
|
181
219
|
headers["x-cloudcms-server-version"] = process.env.CLOUDCMS_APPSERVER_PACKAGE_VERSION;
|
|
182
|
-
|
|
220
|
+
|
|
183
221
|
// keep alive
|
|
184
222
|
//req.headers["connection"] = "keep-alive";
|
|
185
|
-
|
|
223
|
+
|
|
186
224
|
// if the incoming request didn't have an "Authorization" header
|
|
187
225
|
// and we have a logged in Gitana User via Auth, then set authorization header to Bearer Access Token
|
|
188
226
|
if (!req.headers["authorization"])
|
|
@@ -196,85 +234,22 @@ var createProxyHandler = function(proxyTarget, pathPrefix)
|
|
|
196
234
|
headers["authorization"] = "Bearer " + req.gitana_proxy_access_token;
|
|
197
235
|
}
|
|
198
236
|
}
|
|
199
|
-
};
|
|
200
|
-
webConfig.onRes = function(req, res, proxyRes) {
|
|
201
|
-
|
|
202
|
-
if (req.gitana_user)
|
|
203
|
-
{
|
|
204
|
-
var chunks = [];
|
|
205
|
-
|
|
206
|
-
// triggers on data receive
|
|
207
|
-
proxyRes.on('data', function(chunk) {
|
|
208
|
-
// add received chunk to chunks array
|
|
209
|
-
chunks.push(chunk);
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
proxyRes.on("end", function () {
|
|
213
|
-
|
|
214
|
-
if (proxyRes.statusCode === 401)
|
|
215
|
-
{
|
|
216
|
-
var text = "" + Buffer.concat(chunks);
|
|
217
|
-
if (text && (text.indexOf("invalid_token") > -1) || (text.indexOf("invalid_grant") > -1))
|
|
218
|
-
{
|
|
219
|
-
var identifier = req.identity_properties.provider_id + "/" + req.identity_properties.user_identifier;
|
|
220
237
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
var cleanup = function (full)
|
|
233
|
-
{
|
|
234
|
-
delete Gitana.APPS[req.identity_properties.token];
|
|
235
|
-
delete Gitana.PLATFORM_CACHE[req.identity_properties.token];
|
|
236
|
-
|
|
237
|
-
if (full) {
|
|
238
|
-
auth.removeUserCacheEntry(identifier);
|
|
239
|
-
}
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
// null out the access token
|
|
243
|
-
// this will force the refresh token to be used to get a new one on the next request
|
|
244
|
-
req.gitana_user.getDriver().http.refresh(function (err) {
|
|
245
|
-
|
|
246
|
-
if (err) {
|
|
247
|
-
cleanup(true);
|
|
248
|
-
req.log("Invalidated auth state for gitana user: " + req.identity_properties.token);
|
|
249
|
-
return releaseLockFn();
|
|
250
|
-
}
|
|
238
|
+
return headers;
|
|
239
|
+
};
|
|
240
|
+
// rewrite response headers
|
|
241
|
+
proxyOptions.rewriteHeaders = function(headers)
|
|
242
|
+
{
|
|
243
|
+
return headers;
|
|
244
|
+
};
|
|
245
|
+
// request invoke settings
|
|
246
|
+
//proxyOptions.request = {};
|
|
251
247
|
|
|
252
|
-
|
|
253
|
-
cleanup(true);
|
|
254
|
-
req.log("Refreshed token for gitana user: " + req.identity_properties.token);
|
|
255
|
-
releaseLockFn();
|
|
256
|
-
});
|
|
257
|
-
});
|
|
258
|
-
});
|
|
259
|
-
}
|
|
248
|
+
//////////////////////////////////////////////////////////////////////////
|
|
260
249
|
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
//res.setHeader('x-powered-by', 'cloudcms');
|
|
266
|
-
res.writeHead(proxyRes.statusCode, proxyRes.headers)
|
|
267
|
-
proxyRes.pipe(res)
|
|
268
|
-
};
|
|
269
|
-
|
|
270
250
|
var proxyRequestHandler = function(req, res) {
|
|
271
|
-
proxy
|
|
272
|
-
defaultWebHandler(err, req, res);
|
|
273
|
-
});
|
|
251
|
+
proxy(req, res, pathPrefix, proxyOptions);
|
|
274
252
|
};
|
|
275
|
-
|
|
276
|
-
// cookie domain rewrite?
|
|
277
|
-
// not needed - this is handled intrinsically by http2-proxy
|
|
278
253
|
|
|
279
254
|
return proxyRequestHandler;
|
|
280
255
|
};
|