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 @@ -142,7 +142,7 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
$scope.chatMessagesUnseen = 0;
$scope.autoAccept = null;
$scope.isCollapsed = true;
$scope.master = {
$scope.defaults = {
displayName: null,
buddyPicture: null,
message: null,
@ -154,6 +154,7 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte @@ -154,6 +154,7 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
language: ""
}
};
$scope.master = angular.copy($scope.defaults);
// Data voids.
var cache = {};
@ -168,6 +169,10 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte @@ -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) {
// This is the connection status to signaling server.
$scope.$emit("status", status);
@ -195,10 +200,6 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte @@ -195,10 +200,6 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
};
}());
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.refreshWebrtcSettings = function() {
if (!$window.webrtcDetectedBrowser) {
@ -331,6 +332,26 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte @@ -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() {
var oldState = null;
return function(status, force) {
@ -351,18 +372,6 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte @@ -351,18 +372,6 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
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 dialer = playSound.interval("dial", null, 4000);
var dialerEnabled = false;
@ -410,6 +419,8 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte @@ -410,6 +419,8 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
console.error("Failed to authorize session", status, data);
mediaStream.users.forget();
});
} else {
$scope.loadedUserlogin = false;
}
}
@ -641,6 +652,8 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte @@ -641,6 +652,8 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'webrtc.adapte
console.info("Session is now authenticated:", 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.

6
static/js/directives/settings.js

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

5
static/js/services/appdata.js

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

52
static/js/services/usersettingsdata.js

@ -18,32 +18,60 @@ @@ -18,32 +18,60 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
define([], function() {
define(["sjcl"], function(sjcl) {
// userSettingsData
return ["localStorage", function(localStorage) {
return ["localStorage", "mediaStream", "appData", function(localStorage, mediaStream, appData) {
var UserSettingsData = function(key) {
this.key = key
var UserSettingsData = function(prefix) {
this.prefix = prefix
this.suffix = "";
this.key = null;
};
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() {
var raw = localStorage.getItem(this.getId());
console.log("Found stored user data:", raw);
if (raw) {
try {
if (this.key) {
raw = sjcl.decrypt(this.key, raw);
}
console.log("Found stored user data:", raw);
return JSON.parse(raw);
} catch(e) {}
} catch(e) {
console.warn("Failed to load stored user data:", e);
}
}
return null;
};
UserSettingsData.prototype.save = function(data) {
var raw = JSON.stringify(data);
if (this.key) {
// Encrypt.
raw = sjcl.encrypt(this.key, raw);
}
localStorage.setItem(this.getId(), raw)
};
@ -51,7 +79,15 @@ define([], function() { @@ -51,7 +79,15 @@ define([], function() {
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