Browse Source

Implements HTTP POST query for fetching app configuration.

j8
paweldomas 9 years ago
parent
commit
a7048fba06

+ 31
- 2
app.js View File

16
         this.settings = require("./modules/settings/Settings");
16
         this.settings = require("./modules/settings/Settings");
17
         this.DTMF = require("./modules/DTMF/DTMF");
17
         this.DTMF = require("./modules/DTMF/DTMF");
18
         this.members = require("./modules/members/MemberList");
18
         this.members = require("./modules/members/MemberList");
19
+        this.configFetch = require("./modules/config/HttpConfigFetch");
19
     }
20
     }
20
 };
21
 };
21
 
22
 
30
     APP.members.start();
31
     APP.members.start();
31
 }
32
 }
32
 
33
 
34
+/**
35
+ * If we have HTTP endpoint for getting confgi.json configured we're going to
36
+ * read it and override properties from config.js and interfaceConfig.js.
37
+ * If there is no endpoint we'll just continue with initialization.
38
+ * Keep in mind that if the endpoint has been configured and we fail to obtain
39
+ * the config for any reason then the conference won't start and error message
40
+ * will be displayed to the user.
41
+ */
42
+function obtainConfigAndInit() {
43
+    if (config.configLocation) {
44
+        APP.configFetch.obtainConfig(
45
+            config.configLocation, APP.UI.getRoomNode(),
46
+            // Get config result callback
47
+            function(success, error) {
48
+                if (success) {
49
+                    init();
50
+                } else {
51
+                    // Show obtain config error,
52
+                    // pass the error object for report
53
+                    APP.UI.messageHandler.openReportDialog(
54
+                        null, "dialog.connectError", error);
55
+                }
56
+            });
57
+    } else {
58
+        init();
59
+    }
60
+}
61
+
33
 
62
 
34
 $(document).ready(function () {
63
 $(document).ready(function () {
35
 
64
 
36
-    var URLProcessor = require("./modules/URLProcessor/URLProcessor");
65
+    var URLProcessor = require("./modules/config/URLProcessor");
37
     URLProcessor.setConfigParametersFromUrl();
66
     URLProcessor.setConfigParametersFromUrl();
38
     APP.init();
67
     APP.init();
39
 
68
 
42
     if(APP.API.isEnabled())
71
     if(APP.API.isEnabled())
43
         APP.API.init();
72
         APP.API.init();
44
 
73
 
45
-    APP.UI.start(init);
74
+    APP.UI.start(obtainConfigAndInit);
46
 
75
 
47
 });
76
 });
48
 
77
 

+ 1
- 0
config.js View File

1
 var config = {
1
 var config = {
2
+//    configLocation: './config.json', // see ./modules/HttpConfigFetch.js
2
     hosts: {
3
     hosts: {
3
         domain: 'jitsi-meet.example.com',
4
         domain: 'jitsi-meet.example.com',
4
         //anonymousdomain: 'guest.example.com',
5
         //anonymousdomain: 'guest.example.com',

+ 15
- 10
modules/UI/UI.js View File

33
 var MemberEvents = require("../../service/members/Events");
33
 var MemberEvents = require("../../service/members/Events");
34
 
34
 
35
 var eventEmitter = new EventEmitter();
35
 var eventEmitter = new EventEmitter();
36
+var roomNode = null;
36
 var roomName = null;
37
 var roomName = null;
37
 
38
 
38
 
39
 
684
     return VideoLayout.getLargeVideoResource();
685
     return VideoLayout.getLargeVideoResource();
685
 };
686
 };
686
 
687
 
687
-UI.generateRoomName = function() {
688
-    if(roomName)
689
-        return roomName;
690
-    var roomnode = null;
688
+UI.getRoomNode = function () {
689
+    if (roomNode)
690
+        return roomNode;
691
     var path = window.location.pathname;
691
     var path = window.location.pathname;
692
 
692
 
693
     // determinde the room node from the url
693
     // determinde the room node from the url
694
     // TODO: just the roomnode or the whole bare jid?
694
     // TODO: just the roomnode or the whole bare jid?
695
     if (config.getroomnode && typeof config.getroomnode === 'function') {
695
     if (config.getroomnode && typeof config.getroomnode === 'function') {
696
         // custom function might be responsible for doing the pushstate
696
         // custom function might be responsible for doing the pushstate
697
-        roomnode = config.getroomnode(path);
697
+        roomNode = config.getroomnode(path);
698
     } else {
698
     } else {
699
         /* fall back to default strategy
699
         /* fall back to default strategy
700
          * this is making assumptions about how the URL->room mapping happens.
700
          * this is making assumptions about how the URL->room mapping happens.
705
          }
705
          }
706
          */
706
          */
707
         if (path.length > 1) {
707
         if (path.length > 1) {
708
-            roomnode = path.substr(1).toLowerCase();
708
+            roomNode = path.substr(1).toLowerCase();
709
         } else {
709
         } else {
710
             var word = RoomNameGenerator.generateRoomWithoutSeparator();
710
             var word = RoomNameGenerator.generateRoomWithoutSeparator();
711
-            roomnode = word.toLowerCase();
712
-
711
+            roomNode = word.toLowerCase();
713
             window.history.pushState('VideoChat',
712
             window.history.pushState('VideoChat',
714
-                    'Room: ' + word, window.location.pathname + word);
713
+                'Room: ' + word, window.location.pathname + word);
715
         }
714
         }
716
     }
715
     }
716
+    return roomNode;
717
+};
717
 
718
 
718
-    roomName = roomnode + '@' + config.hosts.muc;
719
+UI.generateRoomName = function () {
720
+    if (roomName)
721
+        return roomName;
722
+    var roomNode = UI.getRoomNode();
723
+    roomName = roomNode + '@' + config.hosts.muc;
719
     return roomName;
724
     return roomName;
720
 };
725
 };
721
 
726
 

+ 0
- 50
modules/URLProcessor/URLProcessor.js View File

1
-/* global $, $iq, config, interfaceConfig */
2
-var params = {};
3
-function getConfigParamsFromUrl() {
4
-    if(!location.hash)
5
-        return {};
6
-    var hash = location.hash.substr(1);
7
-    var result = {};
8
-    hash.split("&").forEach(function(part) {
9
-        var item = part.split("=");
10
-        result[item[0]] = JSON.parse(
11
-            decodeURIComponent(item[1]).replace(/\\&/, "&"));
12
-    });
13
-    return result;
14
-}
15
-
16
-params = getConfigParamsFromUrl();
17
-
18
-var URLProcessor = {
19
-    setConfigParametersFromUrl: function () {
20
-        for(var key in params) {
21
-            if(typeof key !== "string")
22
-                continue;
23
-
24
-            var confObj = null, confKey;
25
-            if (key.indexOf("config.") === 0) {
26
-                confObj = config;
27
-                confKey = key.substr("config.".length);
28
-            } else if (key.indexOf("interfaceConfig.") === 0) {
29
-                confObj = interfaceConfig;
30
-                confKey = key.substr("interfaceConfig.".length);
31
-            }
32
-
33
-            if (!confObj)
34
-                continue;
35
-
36
-            var value = params[key];
37
-            if (confObj[confKey] && typeof confObj[confKey] !== typeof value)
38
-            {
39
-                console.warn("The type of " + key +
40
-                    " is wrong. That parameter won't be updated in config.js.");
41
-                continue;
42
-            }
43
-
44
-            confObj[confKey] = value;
45
-        }
46
-
47
-    }
48
-};
49
-
50
-module.exports = URLProcessor;

+ 55
- 0
modules/config/HttpConfigFetch.js View File

1
+/* global $, $iq, config, interfaceConfig */
2
+
3
+var configUtil = require('./Util');
4
+
5
+var HttpConfig = {
6
+    /**
7
+     * Sends HTTP POST request to specified <tt>endpoint</tt>. In request
8
+     * the name of the room is included in JSON format:
9
+     * {
10
+     *   "rooomName": "someroom12345"
11
+     * }
12
+     * @param endpoint the name of HTTP endpoint to which HTTP POST request will
13
+     *                 be sent.
14
+     * @param roomName the name of the conference room for which config will be
15
+     *                 requested.
16
+     * @param complete
17
+     */
18
+    obtainConfig: function (endpoint, roomName, complete) {
19
+        console.info(
20
+            "Send config request to " + endpoint + " for room: " + roomName);
21
+
22
+        var request = new XMLHttpRequest();
23
+        var error = null;
24
+        request.onreadystatechange = function (aEvt) {
25
+            if (request.readyState == 4) {
26
+                var status = request.status;
27
+                if (status === 200) {
28
+                    try {
29
+                        var data = JSON.parse(request.responseText);
30
+                        configUtil.overrideConfigJSON(
31
+                            config, interfaceConfig, data);
32
+                        complete(true);
33
+                        return;
34
+                    } catch (exception) {
35
+                        console.error("Parse config error: ", exception);
36
+                        error = exception;
37
+                    }
38
+                } else {
39
+                    console.error("Get config error: ", request, status);
40
+                    error = "Get config response status: " + status;
41
+                }
42
+                complete(false, error);
43
+            }
44
+        };
45
+
46
+        request.open("POST", endpoint, true);
47
+
48
+        request.setRequestHeader(
49
+            "Content-Type", "application/json;charset=UTF-8");
50
+
51
+        request.send({ "roomName": roomName });
52
+    }
53
+};
54
+
55
+module.exports = HttpConfig;

+ 65
- 0
modules/config/URLProcessor.js View File

1
+/* global $, $iq, config, interfaceConfig */
2
+var configUtils = require('./Util');
3
+var params = {};
4
+function getConfigParamsFromUrl() {
5
+    if (!location.hash)
6
+        return {};
7
+    var hash = location.hash.substr(1);
8
+    var result = {};
9
+    hash.split("&").forEach(function (part) {
10
+        var item = part.split("=");
11
+        result[item[0]] = JSON.parse(
12
+            decodeURIComponent(item[1]).replace(/\\&/, "&"));
13
+    });
14
+    return result;
15
+}
16
+
17
+params = getConfigParamsFromUrl();
18
+
19
+var URLProcessor = {
20
+    setConfigParametersFromUrl: function () {
21
+        // Convert 'params' to JSON object
22
+        // We have:
23
+        // {
24
+        //   "config.disableAudioLevels": false,
25
+        //   "config.channelLastN": -1,
26
+        //   "interfaceConfig.APP_NAME": "Jitsi Meet"
27
+        // }
28
+        // We want to have:
29
+        // {
30
+        //   "config": {
31
+        //     "disableAudioLevels": false,
32
+        //     "channelLastN": -1
33
+        //   },
34
+        //   interfaceConfig: {
35
+        //     APP_NAME: "Jitsi Meet"
36
+        //   }
37
+        // }
38
+        var configJSON = {
39
+            config: {},
40
+            interfaceConfig: {}
41
+        };
42
+        for (var key in params) {
43
+            if (typeof key !== "string") {
44
+                console.warn("Invalid config key: ", key);
45
+                continue;
46
+            }
47
+            var confObj = null, confKey;
48
+            if (key.indexOf("config.") === 0) {
49
+                confObj = configJSON.config;
50
+                confKey = key.substr("config.".length);
51
+            } else if (key.indexOf("interfaceConfig.") === 0) {
52
+                confObj = configJSON.interfaceConfig;
53
+                confKey = key.substr("interfaceConfig.".length);
54
+            }
55
+
56
+            if (!confObj)
57
+                continue;
58
+
59
+            confObj[confKey] = params[key];
60
+        }
61
+        configUtils.overrideConfigJSON(config, interfaceConfig, configJSON);
62
+    }
63
+};
64
+
65
+module.exports = URLProcessor;

+ 49
- 0
modules/config/Util.js View File

1
+/* global $ */
2
+var ConfigUtil = {
3
+    /**
4
+     * Method overrides JSON properties in <tt>config</tt> and
5
+     * <tt>interfaceConfig</tt> Objects with the values from <tt>newConfig</tt>
6
+     * @param config the config object for which we'll be overriding properties
7
+     * @param interfaceConfig the interfaceConfig object for which we'll be
8
+     *                        overriding properties.
9
+     * @param newConfig object containing configuration properties. Destination
10
+     *        object is selected based on root property name:
11
+     *        {
12
+     *          config: {
13
+     *             // config.js properties to be
14
+     *          },
15
+     *          interfaceConfig: {
16
+     *             // interfaceConfig.js properties here
17
+     *          }
18
+     *        }
19
+     */
20
+    overrideConfigJSON: function (config, interfaceConfig, newConfig) {
21
+        for (var configRoot in newConfig) {
22
+
23
+            var confObj = null;
24
+            if (configRoot == "config") {
25
+                confObj = config;
26
+            } else if (configRoot == "interfaceConfig") {
27
+                confObj = interfaceConfig;
28
+            } else {
29
+                continue;
30
+            }
31
+
32
+            for (var key in newConfig[configRoot]) {
33
+                var value = newConfig[configRoot][key];
34
+                if (confObj[key] && typeof confObj[key] !== typeof value)
35
+                {
36
+                    console.warn(
37
+                        "The type of " + key +
38
+                        " is wrong. That parameter won't be updated in: ",
39
+                        confObj);
40
+                    continue;
41
+                }
42
+                console.info("Overriding " + key + " with: " + value);
43
+                confObj[key] = value;
44
+            }
45
+        }
46
+    }
47
+};
48
+
49
+module.exports = ConfigUtil;

+ 4
- 1
modules/xmpp/moderator.js View File

35
 // Sip gateway can be enabled by configuring Jigasi host in config.js or
35
 // Sip gateway can be enabled by configuring Jigasi host in config.js or
36
 // it will be enabled automatically if focus detects the component through
36
 // it will be enabled automatically if focus detects the component through
37
 // service discovery.
37
 // service discovery.
38
-var sipGatewayEnabled = config.hosts.call_control !== undefined;
38
+var sipGatewayEnabled;
39
 
39
 
40
 var eventEmitter = null;
40
 var eventEmitter = null;
41
 
41
 
65
         this.xmppService = xmpp;
65
         this.xmppService = xmpp;
66
         eventEmitter = emitter;
66
         eventEmitter = emitter;
67
 
67
 
68
+        sipGatewayEnabled =
69
+            config.hosts && config.hosts.call_control !== undefined;
70
+
68
         // Message listener that talks to POPUP window
71
         // Message listener that talks to POPUP window
69
         function listener(event) {
72
         function listener(event) {
70
             if (event.data && event.data.sessionId) {
73
             if (event.data && event.data.sessionId) {

+ 5
- 1
modules/xmpp/recording.js View File

10
  * Whether to use a jirecon component for recording, or use the videobridge
10
  * Whether to use a jirecon component for recording, or use the videobridge
11
  * through COLIBRI.
11
  * through COLIBRI.
12
  */
12
  */
13
-var useJirecon = (typeof config.hosts.jirecon != "undefined");
13
+var useJirecon;
14
 
14
 
15
 /**
15
 /**
16
  * The ID of the jirecon recording session. Jirecon generates it when we
16
  * The ID of the jirecon recording session. Jirecon generates it when we
109
 }
109
 }
110
 
110
 
111
 var Recording = {
111
 var Recording = {
112
+    init: function () {
113
+        useJirecon = config.hosts &&
114
+            (typeof config.hosts.jirecon != "undefined");
115
+    },
112
     toggleRecording: function (tokenEmptyCallback, recordingStateChangeCallback, connection) {
116
     toggleRecording: function (tokenEmptyCallback, recordingStateChangeCallback, connection) {
113
         if (!Moderator.isModerator()) {
117
         if (!Moderator.isModerator()) {
114
             console.log(
118
             console.log(

+ 1
- 0
modules/xmpp/xmpp.js View File

270
         initStrophePlugins();
270
         initStrophePlugins();
271
         registerListeners();
271
         registerListeners();
272
         Moderator.init(this, eventEmitter);
272
         Moderator.init(this, eventEmitter);
273
+        Recording.init();
273
         var configDomain = config.hosts.anonymousdomain || config.hosts.domain;
274
         var configDomain = config.hosts.anonymousdomain || config.hosts.domain;
274
         // Force authenticated domain if room is appended with '?login=true'
275
         // Force authenticated domain if room is appended with '?login=true'
275
         if (config.hosts.anonymousdomain &&
276
         if (config.hosts.anonymousdomain &&

Loading…
Cancel
Save