Browse Source

Implemented per user encryption for locally stored user data.

pull/100/head
Simon Eisenmann 11 years ago
parent
commit
cd9157fffd
  1. 47
      static/js/controllers/mediastreamcontroller.js
  2. 6
      static/js/directives/settings.js
  3. 5
      static/js/services/appdata.js
  4. 52
      static/js/services/usersettingsdata.js

47
static/js/controllers/mediastreamcontroller.js

@ -142,7 +142,7 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
$scope.chatMessagesUnseen = 0; $scope.chatMessagesUnseen = 0;
$scope.autoAccept = null; $scope.autoAccept = null;
$scope.isCollapsed = true; $scope.isCollapsed = true;
$scope.master = { $scope.defaults = {
displayName: null, displayName: null,
buddyPicture: null, buddyPicture: null,
message: null, message: null,
@ -154,6 +154,7 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
language: "" language: ""
} }
}; };
$scope.master = angular.copy($scope.defaults);
// Data voids. // Data voids.
var cache = {}; var cache = {};
@ -168,6 +169,10 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
}; };
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.setStatus = function(status) { $scope.setStatus = function(status) {
// This is the connection status to signaling server. // This is the connection status to signaling server.
$scope.$emit("status", status); $scope.$emit("status", status);
@ -195,10 +200,6 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
}; };
}()); }());
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.refreshWebrtcSettings = function() { $scope.refreshWebrtcSettings = function() {
if (!$window.webrtcDetectedBrowser) { if (!$window.webrtcDetectedBrowser) {
@ -331,6 +332,26 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
} }
}; };
// Load user settings.
$scope.loadUserSettings = function(norefresh, clear) {
if (clear) {
$scope.master = angular.copy($scope.defaults);
}
var storedUser = userSettingsData.load();
if (storedUser) {
$scope.user = $.extend(true, {}, $scope.master, storedUser);
$scope.user.settings = $.extend(true, {}, $scope.user.settings, $scope.master.settings, $scope.user.settings);
$scope.update($scope.user, norefresh);
$scope.loadedUser = storedUser.displayName && true;
// Add room definition to root to be availale on initial connect.
$rootScope.roomid = $scope.user.settings.defaultRoom || "";
} else {
$scope.loadedUser = false;
}
$scope.reset();
};
$scope.loadUserSettings(true);
$scope.toggleBuddylist = (function() { $scope.toggleBuddylist = (function() {
var oldState = null; var oldState = null;
return function(status, force) { return function(status, force) {
@ -351,18 +372,6 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
mediaStream.webrtc.setAudioMute(cameraMute); mediaStream.webrtc.setAudioMute(cameraMute);
}); });
// Load user settings.
var storedUser = userSettingsData.load();
if (storedUser) {
$scope.user = $.extend(true, {}, $scope.master, storedUser);
$scope.user.settings = $.extend(true, {}, $scope.user.settings, $scope.master.settings, $scope.user.settings);
$scope.update($scope.user, true);
$scope.loadedUser = storedUser.displayName && true;
// Add room definition to root to be availale on initial connect.
$rootScope.roomid = $scope.user.settings.defaultRoom || "";
}
$scope.reset();
var ringer = playSound.interval("ring", null, 4000); var ringer = playSound.interval("ring", null, 4000);
var dialer = playSound.interval("dial", null, 4000); var dialer = playSound.interval("dial", null, 4000);
var dialerEnabled = false; var dialerEnabled = false;
@ -410,6 +419,8 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
console.error("Failed to authorize session", status, data); console.error("Failed to authorize session", status, data);
mediaStream.users.forget(); mediaStream.users.forget();
}); });
} else {
$scope.loadedUserlogin = false;
} }
} }
@ -641,6 +652,8 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
console.info("Session is now authenticated:", userid, suserid); console.info("Session is now authenticated:", userid, suserid);
} }
appData.e.triggerHandler("authenticationChanged", [userid, suserid]); appData.e.triggerHandler("authenticationChanged", [userid, suserid]);
// Load user settings after authentication changed.
$scope.loadUserSettings(false, true);
}); });
// Apply all layout stuff as classes to our element. // Apply all layout stuff as classes to our element.

6
static/js/directives/settings.js

@ -64,15 +64,18 @@ define(['jquery', 'underscore', 'text!partials/settings.html'], function($, _, t
localStorage.removeItem("mediastream-access-code"); localStorage.removeItem("mediastream-access-code");
} }
}; };
$scope.cancelSettings = function() { $scope.cancelSettings = function() {
$scope.reset(); $scope.reset();
$scope.layout.settings = false; $scope.layout.settings = false;
}; };
$scope.requestDesktopNotifyPermission = function() { $scope.requestDesktopNotifyPermission = function() {
$scope.desktopNotify.requestPermission(function() { $scope.desktopNotify.requestPermission(function() {
safeApply($scope); safeApply($scope);
}); });
}; };
$scope.openContactsManager = function() { $scope.openContactsManager = function() {
dialogs.create( dialogs.create(
"/contactsmanager/main.html", "/contactsmanager/main.html",
@ -103,9 +106,11 @@ define(['jquery', 'underscore', 'text!partials/settings.html'], function($, _, t
//console.log("master sources updates", $scope.master); //console.log("master sources updates", $scope.master);
$scope.refreshWebrtcSettings(); $scope.refreshWebrtcSettings();
}; };
$scope.mediaSources.refresh(function() { $scope.mediaSources.refresh(function() {
safeApply($scope, $scope.checkDefaultMediaSources); safeApply($scope, $scope.checkDefaultMediaSources);
}); });
$scope.$watch("layout.settings", function(showSettings, oldValue) { $scope.$watch("layout.settings", function(showSettings, oldValue) {
if (showSettings) { if (showSettings) {
$scope.desktopNotify.refresh(); $scope.desktopNotify.refresh();
@ -129,6 +134,7 @@ define(['jquery', 'underscore', 'text!partials/settings.html'], function($, _, t
$scope.saveSettings(); $scope.saveSettings();
} }
}); });
}]; }];
var link = function($scope, $element) {}; var link = function($scope, $element) {};

5
static/js/services/appdata.js

@ -23,8 +23,9 @@ define(["jquery"], function($) {
// appData.e events: // appData.e events:
// subscribe these events with appData.e.on(eventname, function() {}). // subscribe these events with appData.e.on(eventname, function() {}).
// //
// - authenticationChanged(event, userid) // - authenticationChanged(event, userid, suserid)
// userid (string) : Public user id of the authenitcated user. // userid (string) : Public user id of the authenticated user.
// suserid (string) : Private user id of the authenticated user.
// //
// - selfReceived(event, self) // - selfReceived(event, self)
// self (object) : Self document as received from API. // self (object) : Self document as received from API.

52
static/js/services/usersettingsdata.js

@ -18,32 +18,60 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
define([], function() { define(["sjcl"], function(sjcl) {
// userSettingsData // userSettingsData
return ["localStorage", function(localStorage) { return ["localStorage", "mediaStream", "appData", function(localStorage, mediaStream, appData) {
var UserSettingsData = function(key) { var UserSettingsData = function(prefix) {
this.key = key this.prefix = prefix
this.suffix = "";
this.key = null;
}; };
UserSettingsData.prototype.getId = function() { UserSettingsData.prototype.getId = function() {
return this.key; var id = this.prefix;
if (this.suffix) {
id = id + "_" + this.suffix;
}
return id;
};
UserSettingsData.prototype.setEncryption = function(id, secret) {
if (id) {
this.key = sjcl.codec.base64.fromBits(sjcl.hash.sha256.hash(secret+mediaStream.config.Token));
var hmac = new sjcl.misc.hmac(this.key);
this.suffix = sjcl.codec.base64.fromBits(hmac.encrypt(id+this.prefix));
} else {
this.suffix = "";
this.key = null;
}
}; };
UserSettingsData.prototype.load = function() { UserSettingsData.prototype.load = function() {
var raw = localStorage.getItem(this.getId()); var raw = localStorage.getItem(this.getId());
console.log("Found stored user data:", raw);
if (raw) { if (raw) {
try { try {
if (this.key) {
raw = sjcl.decrypt(this.key, raw);
}
console.log("Found stored user data:", raw);
return JSON.parse(raw); return JSON.parse(raw);
} catch(e) {} } catch(e) {
console.warn("Failed to load stored user data:", e);
}
} }
return null; return null;
}; };
UserSettingsData.prototype.save = function(data) { UserSettingsData.prototype.save = function(data) {
var raw = JSON.stringify(data); var raw = JSON.stringify(data);
if (this.key) {
// Encrypt.
raw = sjcl.encrypt(this.key, raw);
}
localStorage.setItem(this.getId(), raw) localStorage.setItem(this.getId(), raw)
}; };
@ -51,7 +79,15 @@ define([], function() {
localStorage.removeItem(this.getId()); localStorage.removeItem(this.getId());
}; };
return new UserSettingsData("mediastream-user"); // Create our default instance.
var userSettingsData = new UserSettingsData("mediastream-user");
// Bind to authentication to encrypt stored data per user.
appData.e.on("authenticationChanged", function(event, userid, suserid) {
userSettingsData.setEncryption(userid, suserid);
});
return userSettingsData;
}]; }];

Loading…
Cancel
Save