From 555bd61325bf7e8f7b09b92287097962242a1a54 Mon Sep 17 00:00:00 2001 From: Lance Cooper Date: Tue, 28 Oct 2014 15:07:13 +0100 Subject: [PATCH] Add basic support for pin locked rooms to the web application. --- .../js/controllers/mediastreamcontroller.js | 1 + static/js/directives/roombar.js | 8 ++- static/js/mediastream/api.js | 8 ++- static/js/services/mediastream.js | 2 +- static/js/services/roompin.js | 58 +++++++++++++++ static/js/services/rooms.js | 70 ++++++++++++++++--- static/js/services/services.js | 9 ++- 7 files changed, 137 insertions(+), 19 deletions(-) create mode 100644 static/js/services/roompin.js diff --git a/static/js/controllers/mediastreamcontroller.js b/static/js/controllers/mediastreamcontroller.js index 5f80b865..7e639f32 100644 --- a/static/js/controllers/mediastreamcontroller.js +++ b/static/js/controllers/mediastreamcontroller.js @@ -545,6 +545,7 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte // Unmark authorization process. if (data.Userid) { $rootScope.authorizing(false); + $rootScope.$broadcast("authorization.succeeded"); } else if (!$rootScope.authorizing()) { // Trigger user data load when not in authorizing phase. $scope.loadUserSettings(); diff --git a/static/js/directives/roombar.js b/static/js/directives/roombar.js index 872375cf..2ab20274 100644 --- a/static/js/directives/roombar.js +++ b/static/js/directives/roombar.js @@ -24,6 +24,9 @@ define(['underscore', 'text!partials/roombar.html'], function(_, template) { return ["$window", "rooms", function($window, rooms) { var link = function($scope) { + var clearRoomName = function(ev) { + $scope.currentRoomName = $scope.newRoomName = ""; + }; //console.log("roomBar directive link", arguments); $scope.layout.roombar = false; @@ -51,9 +54,7 @@ define(['underscore', 'text!partials/roombar.html'], function(_, template) { $scope.currentRoomName = $scope.newRoomName = room.Name; }); - $scope.$on("room.left", function(ev) { - $scope.currentRoomName = $scope.newRoomName = ""; - }); + $scope.$on("room.left", clearRoomName); $scope.$watch("newRoomName", function(name) { if (name === $scope.currentRoomName) { @@ -61,6 +62,7 @@ define(['underscore', 'text!partials/roombar.html'], function(_, template) { } }); + clearRoomName(); }; return { diff --git a/static/js/mediastream/api.js b/static/js/mediastream/api.js index 5e6b3deb..ca56ddf5 100644 --- a/static/js/mediastream/api.js +++ b/static/js/mediastream/api.js @@ -229,13 +229,19 @@ define(['jquery', 'underscore', 'ua-parser'], function($, _, uaparser) { }; - Api.prototype.sendHello = function(name, success, fault) { + Api.prototype.sendHello = function(name, pin, success, fault) { var data = { Version: this.version, Ua: this.userAgent, Id: name }; + if (pin) { + data.Credentials = { + PIN: pin + }; + } + var that = this; var onResponse = function(event, type, data) { if (type === "Welcome") { diff --git a/static/js/services/mediastream.js b/static/js/services/mediastream.js index 517cad6c..238c6e26 100644 --- a/static/js/services/mediastream.js +++ b/static/js/services/mediastream.js @@ -40,7 +40,7 @@ define([ // Create encryption key from server token and browser name. var secureKey = sjcl.codec.base64.fromBits(sjcl.hash.sha256.hash(context.Cfg.Token + uaparser().browser.name)); - var authorizing = false; + var authorizing = context.Cfg.UsersEnabled; $rootScope.authorizing = function(value) { // Boolean flag to indicate that an authentication is currently in progress. if (typeof(value) !== "undefined") { diff --git a/static/js/services/roompin.js b/static/js/services/roompin.js new file mode 100644 index 00000000..b4490e05 --- /dev/null +++ b/static/js/services/roompin.js @@ -0,0 +1,58 @@ +/* + * Spreed WebRTC. + * Copyright (C) 2013-2014 struktur AG + * + * This file is part of Spreed WebRTC. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +define([ +], function() { + + return ["$window", "$q", function($window, $q) { + var pinCache = {}; + var roompin = { + get: function(roomName) { + var cachedPIN = pinCache[roomName]; + return cachedPIN ? cachedPIN : null; + }, + clear: function(roomName) { + delete pinCache[roomName]; + console.log("Cleared PIN for", roomName); + }, + update: function(roomName, pin) { + if (pin) { + pinCache[roomName] = pin; + $window.alert("PIN for room " + roomName + " is now '" + pin + "'"); + } else { + roompin.clear(roomName); + $window.alert("PIN lock has been removed from room " + roomName); + } + }, + requestInteractively: function(roomName) { + var deferred = $q.defer(); + var pin = $window.prompt("Enter the PIN for " + roomName + " below"); + if (pin) { + pinCache[roomName] = pin; + deferred.resolve(); + } else { + deferred.reject(); + } + return deferred.promise; + } + }; + return roompin; + }]; +}); diff --git a/static/js/services/rooms.js b/static/js/services/rooms.js index a5557d73..bae3d9c1 100644 --- a/static/js/services/rooms.js +++ b/static/js/services/rooms.js @@ -19,18 +19,39 @@ * */ define([ + 'angular', 'jquery' -], function($) { +], function(angular, $) { - return ["$window", "$location", "$timeout", "$q", "$route", "$rootScope", "$http", "globalContext", "safeApply", "connector", "api", "restURL", function($window, $location, $timeout, $q, $route, $rootScope, $http, globalContext, safeApply, connector, api, restURL) { + return ["$window", "$location", "$timeout", "$q", "$route", "$rootScope", "$http", "globalContext", "safeApply", "connector", "api", "restURL", "roompin", function($window, $location, $timeout, $q, $route, $rootScope, $http, globalContext, safeApply, connector, api, restURL, roompin) { var url = restURL.api("rooms"); var requestedRoomName = ""; var currentRoom = null; var joinFailed = function(error) { - console.log("error", error, "while joining room"); setCurrentRoom(null); - rooms.randomRoom(); + + switch(error.Code) { + case "default_room_disabled": + rooms.randomRoom(); + break; + case "invalid_credentials": + roompin.clear(requestedRoomName); + /* falls through */ + case "authorization_required": + roompin.requestInteractively(requestedRoomName).then(joinRequestedRoom, + function() { + console.log("Authentication cancelled, try a different room"); + }); + break; + case "authorization_not_required": + roompin.clear(requestedRoomName); + joinRequestedRoom(); + break; + default: + console.log("Unknown error", error, "while joining room ", requestedRoomName); + break; + } }; var joinRequestedRoom = function() { @@ -43,7 +64,7 @@ define([ if (requestedRoomName !== "" || globalContext.Cfg.DefaultRoomEnabled) { console.log("Joining room", requestedRoomName); requestedRoomName = requestedRoomName ? requestedRoomName : ""; - api.sendHello(requestedRoomName, setCurrentRoom, joinFailed); + api.sendHello(requestedRoomName, roompin.get(requestedRoomName), setCurrentRoom, joinFailed); } else { console.log("Default room disabled, requesting a random room."); setCurrentRoom(null); @@ -68,6 +89,22 @@ define([ } }; + var updateRoom = function(room) { + var response = $q.defer(); + api.requestRoomUpdate(room, response.resolve, response.reject); + return response.promise.then(applyRoomUpdate); + }; + + var applyRoomUpdate = function(room) { + if (room.Credentials) { + roompin.update(currentRoom.Name, room.Credentials.PIN); + delete room.Credentials; + } + currentRoom = room; + $rootScope.$broadcast("room.updated", currentRoom); + return room; + }; + connector.e.on("close error", function() { setCurrentRoom(null); }); @@ -77,8 +114,12 @@ define([ }); api.e.on("received.room", function(event, room) { - currentRoom = room; - $rootScope.$broadcast("room.updated", currentRoom); + applyRoomUpdate(room); + }); + + $rootScope.$on("authorization.succeeded", function() { + // NOTE(lcooper): This will have been skipped earlier, so try again. + joinRequestedRoom(); }); $rootScope.$on("$locationChangeSuccess", function(event) { @@ -144,13 +185,20 @@ define([ } return restURL.room(name); }, - update: function(room) { - var response = $q.defer(); - api.requestRoomUpdate(room, response.resolve, response.reject); - return response.promise; + setPIN: function(pin) { + pin = "" + pin; + var newRoom = angular.copy(currentRoom); + newRoom.Credentials = {PIN: pin}; + return updateRoom(newRoom).then(null, function(error) { + console.log("Failed to set room PIN", error); + return $q.reject(error); + }); } }; + // NOTE(lcooper): For debugging only, do not use this on production. + $window.setRoomPIN = rooms.setPIN; + return rooms; }]; }); diff --git a/static/js/services/services.js b/static/js/services/services.js index 1e49d89e..b5a9975b 100644 --- a/static/js/services/services.js +++ b/static/js/services/services.js @@ -61,7 +61,8 @@ define([ 'services/usersettingsdata', 'services/localstatus', 'services/rooms', - 'services/resturl'], function(_, + 'services/resturl', + 'services/roompin'], function(_, desktopNotify, playSound, safeApply, @@ -102,7 +103,8 @@ chromeExtension, userSettingsData, localStatus, rooms, -restURL) { +restURL, +roompin) { var services = { desktopNotify: desktopNotify, @@ -145,7 +147,8 @@ restURL) { userSettingsData: userSettingsData, localStatus: localStatus, rooms: rooms, - restURL: restURL + restURL: restURL, + roompin: roompin }; var initialize = function(angModule) {