mirror of
https://github.com/moparisthebest/mail
synced 2024-11-23 09:22:23 -05:00
Merge remote-tracking branch 'origin/new_device'
This commit is contained in:
commit
33440ae16f
@ -3,6 +3,7 @@ window.name = 'NG_DEFER_BOOTSTRAP!';
|
|||||||
|
|
||||||
require([
|
require([
|
||||||
'angular',
|
'angular',
|
||||||
|
'js/controller/account',
|
||||||
'js/controller/login',
|
'js/controller/login',
|
||||||
'js/controller/login-initial',
|
'js/controller/login-initial',
|
||||||
'js/controller/login-new-device',
|
'js/controller/login-new-device',
|
||||||
@ -13,10 +14,10 @@ require([
|
|||||||
'js/controller/navigation',
|
'js/controller/navigation',
|
||||||
'angularRoute',
|
'angularRoute',
|
||||||
'angularTouch'
|
'angularTouch'
|
||||||
], function(angular, LoginCtrl, LoginInitialCtrl, LoginNewDeviceCtrl, LoginExistingCtrl, MailListCtrl, ReadCtrl, WriteCtrl, NavigationCtrl) {
|
], function(angular, AccountCtrl, LoginCtrl, LoginInitialCtrl, LoginNewDeviceCtrl, LoginExistingCtrl, MailListCtrl, ReadCtrl, WriteCtrl, NavigationCtrl) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var app = angular.module('mail', ['ngRoute', 'ngTouch', 'navigation', 'mail-list', 'write', 'read']);
|
var app = angular.module('mail', ['ngRoute', 'ngTouch', 'navigation', 'mail-list', 'write', 'read', 'login-new-device']);
|
||||||
|
|
||||||
// set router paths
|
// set router paths
|
||||||
app.config(function($routeProvider) {
|
app.config(function($routeProvider) {
|
||||||
@ -49,6 +50,7 @@ require([
|
|||||||
app.controller('ReadCtrl', ReadCtrl);
|
app.controller('ReadCtrl', ReadCtrl);
|
||||||
app.controller('WriteCtrl', WriteCtrl);
|
app.controller('WriteCtrl', WriteCtrl);
|
||||||
app.controller('MailListCtrl', MailListCtrl);
|
app.controller('MailListCtrl', MailListCtrl);
|
||||||
|
app.controller('AccountCtrl', AccountCtrl);
|
||||||
|
|
||||||
// manually bootstrap angular due to require.js
|
// manually bootstrap angular due to require.js
|
||||||
angular.element().ready(function() {
|
angular.element().ready(function() {
|
||||||
|
58
src/js/controller/account.js
Normal file
58
src/js/controller/account.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
define(function(require) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var appController = require('js/app-controller'),
|
||||||
|
emailDao;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Controller
|
||||||
|
//
|
||||||
|
|
||||||
|
var AccountCtrl = function($scope) {
|
||||||
|
emailDao = appController._emailDao;
|
||||||
|
|
||||||
|
//
|
||||||
|
// scope functions
|
||||||
|
//
|
||||||
|
|
||||||
|
$scope.hideAccountView = function() {
|
||||||
|
$scope.$parent.$parent.accountOpen = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.exportKeyFile = function() {
|
||||||
|
emailDao._crypto.exportKeys(function(err, keys) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var id = keys.keyId.substring(8,keys.keyId.length);
|
||||||
|
download(keys.publicKeyArmored + keys.privateKeyArmored, id + '.asc', 'text/plain');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// helper functions
|
||||||
|
//
|
||||||
|
|
||||||
|
function download(content, filename, contentType) {
|
||||||
|
contentType = contentType || 'application/octet-stream';
|
||||||
|
chrome.fileSystem.chooseEntry({
|
||||||
|
type: 'saveFile',
|
||||||
|
suggestedName: filename
|
||||||
|
}, function(file) {
|
||||||
|
if (!file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
file.createWriter(function(writer) {
|
||||||
|
writer.onerror = console.error;
|
||||||
|
writer.onwriteend = function() {};
|
||||||
|
writer.write(new Blob([content], { type: contentType }));
|
||||||
|
}, console.error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return AccountCtrl;
|
||||||
|
});
|
@ -1,13 +1,98 @@
|
|||||||
define(function() {
|
define(function(require) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var LoginExistingCtrl = function($scope) {
|
var angular = require('angular'),
|
||||||
|
appController = require('js/app-controller');
|
||||||
|
|
||||||
|
var LoginExistingCtrl = function($scope, $location) {
|
||||||
$scope.confirmPassphrase = function() {
|
$scope.confirmPassphrase = function() {
|
||||||
window.alert('Not implemented yet!');
|
var passphrase = $scope.passphrase,
|
||||||
|
emailDao = appController._emailDao;
|
||||||
|
|
||||||
|
if (!passphrase) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlockCrypto(imapLogin);
|
||||||
|
|
||||||
|
function unlockCrypto(callback) {
|
||||||
|
var userId = emailDao._account.emailAddress;
|
||||||
|
emailDao._keychain.getUserKeyPair(userId, function(err, keypair) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
keypair.privateKey = {
|
||||||
|
_id: keypair.publicKey._id,
|
||||||
|
userId: userId,
|
||||||
|
encryptedKey: $scope.key.privateKeyArmored
|
||||||
|
};
|
||||||
|
emailDao.unlock(keypair, passphrase, function(err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emailDao._keychain.putUserKeyPair(keypair, callback);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function imapLogin(err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// login to imap backend
|
||||||
|
appController._emailDao.imapLogin(function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onLogin();
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function onLogin() {
|
||||||
|
$location.path('/desktop');
|
||||||
|
$scope.$apply();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var ngModule = angular.module('login-new-device', []);
|
||||||
|
ngModule.directive('fileReader', function() {
|
||||||
|
return function(scope, elm) {
|
||||||
|
elm.bind('change', function(e) {
|
||||||
|
var files = e.target.files,
|
||||||
|
reader = new FileReader();
|
||||||
|
|
||||||
|
if (files.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.onload = (function(scope) {
|
||||||
|
return function(e) {
|
||||||
|
var rawKeys = e.target.result,
|
||||||
|
index = rawKeys.indexOf('-----BEGIN PGP PRIVATE KEY BLOCK-----');
|
||||||
|
|
||||||
|
if (index === -1) {
|
||||||
|
console.error('Erroneous key file format!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.key = {
|
||||||
|
publicKeyArmored: rawKeys.substring(0,index),
|
||||||
|
privateKeyArmored: rawKeys.substring(index,rawKeys.length)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})(scope);
|
||||||
|
reader.readAsText(files[0]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
return LoginExistingCtrl;
|
return LoginExistingCtrl;
|
||||||
});
|
});
|
@ -40,7 +40,7 @@ define(function(require) {
|
|||||||
|
|
||||||
function redirect(availableKeys) {
|
function redirect(availableKeys) {
|
||||||
// redirect if needed
|
// redirect if needed
|
||||||
if (!availableKeys.publicKey) {
|
if (typeof availableKeys === 'undefined') {
|
||||||
// no public key available, start onboarding process
|
// no public key available, start onboarding process
|
||||||
$location.path('/login-initial');
|
$location.path('/login-initial');
|
||||||
} else if (!availableKeys.privateKey) {
|
} else if (!availableKeys.privateKey) {
|
||||||
|
@ -13,6 +13,7 @@ define(function(require) {
|
|||||||
var NavigationCtrl = function($scope) {
|
var NavigationCtrl = function($scope) {
|
||||||
$scope.navOpen = false;
|
$scope.navOpen = false;
|
||||||
$scope.writerOpen = false;
|
$scope.writerOpen = false;
|
||||||
|
$scope.accountOpen = false;
|
||||||
|
|
||||||
emailDao = appController._emailDao;
|
emailDao = appController._emailDao;
|
||||||
|
|
||||||
@ -42,6 +43,10 @@ define(function(require) {
|
|||||||
$scope.closeNav();
|
$scope.closeNav();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.showAccountView = function() {
|
||||||
|
$scope.accountOpen = true;
|
||||||
|
};
|
||||||
|
|
||||||
$scope.remove = function(email) {
|
$scope.remove = function(email) {
|
||||||
var trashFolder = _.findWhere($scope.folders, {
|
var trashFolder = _.findWhere($scope.folders, {
|
||||||
type: 'Trash'
|
type: 'Trash'
|
||||||
|
@ -19,6 +19,9 @@ define(['jquery', 'js/app-config'], function($, app) {
|
|||||||
url: uri,
|
url: uri,
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
},
|
||||||
success: function(res) {
|
success: function(res) {
|
||||||
callback(null, res);
|
callback(null, res);
|
||||||
},
|
},
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
"icons": {
|
"icons": {
|
||||||
"128": "img/icon.png"
|
"128": "img/icon.png"
|
||||||
},
|
},
|
||||||
"permissions": [
|
"permissions": [{
|
||||||
|
"fileSystem": ["write"]
|
||||||
|
},
|
||||||
"https://keys.whiteout.io/",
|
"https://keys.whiteout.io/",
|
||||||
"identity", {
|
"identity", {
|
||||||
"socket": [
|
"socket": [
|
||||||
|
10
src/tpl/account.html
Normal file
10
src/tpl/account.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<div class="lightbox-body" ng-controller="AccountCtrl">
|
||||||
|
<header>
|
||||||
|
<h2>Account</h2>
|
||||||
|
<button class="close" ng-click="hideAccountView()" data-action="lightbox-close"></button>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<button ng-click="exportKeyFile()" class="btn" >Download encrypted key file</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -21,4 +21,8 @@
|
|||||||
<!-- lightbox -->
|
<!-- lightbox -->
|
||||||
<div class="lightbox-overlay" ng-class="{'show': writerOpen}">
|
<div class="lightbox-overlay" ng-class="{'show': writerOpen}">
|
||||||
<div class="lightbox lightbox-effect" ng-include="'tpl/write.html'"></div>
|
<div class="lightbox lightbox-effect" ng-include="'tpl/write.html'"></div>
|
||||||
</div><!--/.lightbox-overlay-->
|
</div>
|
||||||
|
<div class="lightbox-overlay" ng-class="{'show': accountOpen}">
|
||||||
|
<div class="lightbox lightbox-effect" ng-include="'tpl/account.html'"></div>
|
||||||
|
</div>
|
||||||
|
<!--/.lightbox-overlay-->
|
@ -1 +1,18 @@
|
|||||||
<p>not implemented yet...</p>
|
<div class="view-login">
|
||||||
|
|
||||||
|
<div class="logo-wrapper">
|
||||||
|
<div class="logo"></div>
|
||||||
|
</div><!--/logo-->
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<h1>Import keyfile</h1>
|
||||||
|
|
||||||
|
<p>You are already registered on another device. To access your communication on this device, please import the encrypted key file.</p>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<div><input type="file" file-reader tabindex="1"></div>
|
||||||
|
<div><input type="password" ng-model="passphrase" placeholder="Passphrase" tabindex="2"></div>
|
||||||
|
<div><button type="submit" ng-click="confirmPassphrase()" class="btn" ng-disabled="!key" tabindex="3">Import</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -13,7 +13,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul class="nav-secondary">
|
<ul class="nav-secondary">
|
||||||
<li><a href="#">Account</a></li>
|
<li><a href="#" ng-click="showAccountView(); $event.preventDefault()">Account</a></li>
|
||||||
<li><a href="#">About whiteout.io</a></li>
|
<li><a href="#">About whiteout.io</a></li>
|
||||||
<li><a href="#">Help</a></li>
|
<li><a href="#">Help</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
Loading…
Reference in New Issue
Block a user