mirror of
https://github.com/moparisthebest/mail
synced 2024-11-26 19:02:20 -05:00
Merge pull request #11 from whiteout-io/dev/choose-account
[WO-207] implement accout selection
This commit is contained in:
commit
66ef501a16
BIN
src/img/google_logo.png
Normal file
BIN
src/img/google_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
src/img/outlook_logo.jpg
Normal file
BIN
src/img/outlook_logo.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 58 KiB |
BIN
src/img/tonline_logo.jpg
Normal file
BIN
src/img/tonline_logo.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
BIN
src/img/yahoo_logo.png
Normal file
BIN
src/img/yahoo_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 178 KiB |
@ -203,12 +203,6 @@ define(function(require) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cachedEmailAddress) {
|
||||
// not first time login... address cached
|
||||
callback(null, cachedEmailAddress);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cachedEmailAddress && !self.isOnline()) {
|
||||
// first time login... must be online
|
||||
callback({
|
||||
@ -217,14 +211,7 @@ define(function(require) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.fetchOAuthToken(function(err, oauth) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, oauth.emailAddress);
|
||||
});
|
||||
callback(null, cachedEmailAddress);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -5,6 +5,7 @@ require([
|
||||
'angular',
|
||||
'js/controller/dialog',
|
||||
'js/controller/popover',
|
||||
'js/controller/add-account',
|
||||
'js/controller/account',
|
||||
'js/controller/login',
|
||||
'js/controller/login-initial',
|
||||
@ -17,7 +18,7 @@ require([
|
||||
'cryptoLib/util',
|
||||
'angularRoute',
|
||||
'angularTouch'
|
||||
], function(angular, DialogCtrl, PopoverCtrl, AccountCtrl, LoginCtrl, LoginInitialCtrl, LoginNewDeviceCtrl, LoginExistingCtrl, MailListCtrl, ReadCtrl, WriteCtrl, NavigationCtrl, util) {
|
||||
], function(angular, DialogCtrl, PopoverCtrl, AddAccountCtrl, AccountCtrl, LoginCtrl, LoginInitialCtrl, LoginNewDeviceCtrl, LoginExistingCtrl, MailListCtrl, ReadCtrl, WriteCtrl, NavigationCtrl, util) {
|
||||
'use strict';
|
||||
|
||||
// reset window.name
|
||||
@ -28,6 +29,10 @@ require([
|
||||
|
||||
// set router paths
|
||||
app.config(function($routeProvider) {
|
||||
$routeProvider.when('/add-account', {
|
||||
templateUrl: 'tpl/add-account.html',
|
||||
controller: AddAccountCtrl
|
||||
});
|
||||
$routeProvider.when('/login', {
|
||||
templateUrl: 'tpl/login.html',
|
||||
controller: LoginCtrl
|
||||
|
31
src/js/controller/add-account.js
Normal file
31
src/js/controller/add-account.js
Normal file
@ -0,0 +1,31 @@
|
||||
define(function(require) {
|
||||
'use strict';
|
||||
|
||||
var appController = require('js/app-controller'),
|
||||
errorUtil = require('js/util/error');
|
||||
|
||||
var AddAccountCtrl = function($scope, $location) {
|
||||
// global state... inherited to all child scopes
|
||||
$scope.$root.state = {};
|
||||
// attach global error handler
|
||||
errorUtil.attachHandler($scope);
|
||||
|
||||
$scope.connectToGoogle = function() {
|
||||
appController.fetchOAuthToken(function(err) {
|
||||
if (err) {
|
||||
$scope.onError(err);
|
||||
return;
|
||||
}
|
||||
|
||||
redirect();
|
||||
});
|
||||
};
|
||||
|
||||
function redirect() {
|
||||
$location.path('/login');
|
||||
$scope.$apply();
|
||||
}
|
||||
};
|
||||
|
||||
return AddAccountCtrl;
|
||||
});
|
@ -33,6 +33,12 @@ define(function(require) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check if account needs to be selected
|
||||
if (!emailAddress) {
|
||||
firstLogin();
|
||||
return;
|
||||
}
|
||||
|
||||
// initiate controller by creating email dao
|
||||
appController.init({
|
||||
emailAddress: emailAddress
|
||||
@ -47,6 +53,11 @@ define(function(require) {
|
||||
});
|
||||
}
|
||||
|
||||
function firstLogin() {
|
||||
$location.path('/add-account');
|
||||
$scope.$apply();
|
||||
}
|
||||
|
||||
function redirect(availableKeys) {
|
||||
// redirect if needed
|
||||
if (typeof availableKeys === 'undefined') {
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
// Views
|
||||
@import "views/shared";
|
||||
@import "views/add-account";
|
||||
@import "views/account";
|
||||
@import "views/dialog";
|
||||
@import "views/navigation";
|
||||
|
125
src/sass/views/_add-account.scss
Normal file
125
src/sass/views/_add-account.scss
Normal file
@ -0,0 +1,125 @@
|
||||
.view-add-account {
|
||||
height: 100%;
|
||||
background-color: $color-grey-lightest;
|
||||
color: $color-grey-dark;
|
||||
|
||||
h1 {
|
||||
padding: 60px 0 50px 0;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
font-size: 32px;
|
||||
line-height: 64px;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
width: 320px;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: $color-grey-lighter;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
height: 68px;
|
||||
cursor: pointer;
|
||||
|
||||
&.google {
|
||||
background-color: white;
|
||||
|
||||
div {
|
||||
width: 164px;
|
||||
height: 58px;
|
||||
margin: 0px auto;
|
||||
padding: 8px 0;
|
||||
|
||||
img {
|
||||
width: 164px;
|
||||
height: 58px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.whiteout {
|
||||
background-color: $color-grey-lightest;
|
||||
|
||||
div {
|
||||
width: 210px;
|
||||
margin: 0 auto;
|
||||
padding: 15px 0;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.outlook {
|
||||
background-color: white;
|
||||
|
||||
div {
|
||||
width: 256px;
|
||||
margin: 0 auto;
|
||||
padding: 13px 0;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.yahoo {
|
||||
background-color: $color-grey-lightest;
|
||||
|
||||
div {
|
||||
width: 181px;
|
||||
margin: 0 auto;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.tonline {
|
||||
background-color: white;
|
||||
|
||||
div {
|
||||
width: 271px;
|
||||
margin: 0 auto;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.other {
|
||||
h3 {
|
||||
margin: 0;
|
||||
line-height: 68px;
|
||||
font-size: 21px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
&.enabled {
|
||||
&:hover,
|
||||
&:focus {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
&:active {
|
||||
opacity: 1;
|
||||
top: 1px;
|
||||
left: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
92
src/tpl/add-account.html
Normal file
92
src/tpl/add-account.html
Normal file
@ -0,0 +1,92 @@
|
||||
<div class="view-add-account">
|
||||
|
||||
<h1>Select email account</h1>
|
||||
|
||||
<ul>
|
||||
<li class="google enabled" popover="#google-info" ng-click="connectToGoogle()">
|
||||
<div><img src="img/google_logo.png" alt="Google Mail"></div>
|
||||
</li>
|
||||
<li class="whiteout disabled" popover="#whiteout-info">
|
||||
<div><img src="img/whiteout_logo.svg" alt="Whiteout Mailbox"></div>
|
||||
</li>
|
||||
<li class="outlook disabled" popover="#outlook-info">
|
||||
<div><img src="img/outlook_logo.jpg" alt="Outlook.com"></div>
|
||||
</li>
|
||||
<li class="yahoo disabled" popover="#yahoo-info">
|
||||
<div><img src="img/yahoo_logo.png" alt="Yahoo! Mail"></div>
|
||||
</li>
|
||||
<li class="tonline disabled" popover="#tonline-info">
|
||||
<div><img src="img/tonline_logo.jpg" alt="T-Online"></div>
|
||||
</li>
|
||||
<li class="other disabled" popover="#custom-info">
|
||||
<h3>Custom server...</h3>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- lightbox -->
|
||||
<div class="lightbox-overlay" ng-class="{'show': state.dialog.open}">
|
||||
<div class="lightbox lightbox-effect view-dialog" ng-include="'tpl/dialog.html'"></div>
|
||||
</div>
|
||||
|
||||
<!-- popovers -->
|
||||
<div id="google-info" class="popover right" ng-controller="PopoverCtrl">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-title"><b>Google Account</b></div>
|
||||
<div class="popover-content">
|
||||
<p>Connect Whiteout Mail to your Gmail or Google Apps account.</p>
|
||||
<p>Encrypted and cleartext messages are stored on Google's servers.</p>
|
||||
<p>No data is sent to our servers.</p>
|
||||
</div>
|
||||
</div><!--/.popover-->
|
||||
|
||||
<div id="whiteout-info" class="popover right" ng-controller="PopoverCtrl">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-title"><b>Whiteout Mailbox (coming soon)</b></div>
|
||||
<div class="popover-content">
|
||||
<p>Connect Whiteout Mail to your secure Whiteout Mailbox.</p>
|
||||
<p>All incoming messages are encrypted at rest and can only be read on your device.</p>
|
||||
<p>Whiteout Mailbox is an email service hosted in Germany.</p>
|
||||
</div>
|
||||
</div><!--/.popover-->
|
||||
|
||||
<div id="outlook-info" class="popover right" ng-controller="PopoverCtrl">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-title"><b>Outlook.com Account (coming soon)</b></div>
|
||||
<div class="popover-content">
|
||||
<p>Connect Whiteout Mail to your Outlook.com account.</p>
|
||||
<p>Encrypted and cleartext messages are stored on Microsoft's servers.</p>
|
||||
<p>No data is sent to our servers.</p>
|
||||
</div>
|
||||
</div><!--/.popover-->
|
||||
|
||||
<div id="yahoo-info" class="popover right" ng-controller="PopoverCtrl">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-title"><b>Yahoo Mail (coming soon)</b></div>
|
||||
<div class="popover-content">
|
||||
<p>Connect Whiteout Mail to your Yahoo Mail account.</p>
|
||||
<p>Encrypted and cleartext messages are stored on Yahoo's servers.</p>
|
||||
<p>No data is sent to our servers.</p>
|
||||
</div>
|
||||
</div><!--/.popover-->
|
||||
|
||||
<div id="tonline-info" class="popover right" ng-controller="PopoverCtrl">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-title"><b>T-Online Account (coming soon)</b></div>
|
||||
<div class="popover-content">
|
||||
<p>Connect Whiteout Mail to your T-Online account.</p>
|
||||
<p>Encrypted and cleartext messages are stored on T-Online's servers.</p>
|
||||
<p>No data is sent to our servers.</p>
|
||||
</div>
|
||||
</div><!--/.popover-->
|
||||
|
||||
<div id="custom-info" class="popover right" ng-controller="PopoverCtrl">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-title"><b>Custom server (coming soon)</b></div>
|
||||
<div class="popover-content">
|
||||
<p>Connect Whiteout Mail to your own email server.</p>
|
||||
<p>Encrypted and cleartext messages are stored on your server.</p>
|
||||
<p>No data is sent to our servers.</p>
|
||||
</div>
|
||||
</div><!--/.popover-->
|
72
test/new-unit/add-account-ctrl-test.js
Normal file
72
test/new-unit/add-account-ctrl-test.js
Normal file
@ -0,0 +1,72 @@
|
||||
define(function(require) {
|
||||
'use strict';
|
||||
|
||||
var expect = chai.expect,
|
||||
angular = require('angular'),
|
||||
mocks = require('angularMocks'),
|
||||
AddAccountCtrl = require('js/controller/add-account'),
|
||||
appController = require('js/app-controller');
|
||||
|
||||
describe('Add Account Controller unit test', function() {
|
||||
var scope, location, ctrl,
|
||||
fetchOAuthTokenStub;
|
||||
|
||||
describe('connectToGoogle', function() {
|
||||
beforeEach(function() {
|
||||
// remember original module to restore later, then replace it
|
||||
fetchOAuthTokenStub = sinon.stub(appController, 'fetchOAuthToken');
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
// restore the app controller module
|
||||
location && location.path && location.path.restore && location.path.restore();
|
||||
fetchOAuthTokenStub.restore();
|
||||
});
|
||||
|
||||
it('should fail on fetchOAuthToken error', function(done) {
|
||||
angular.module('addaccounttest', []);
|
||||
mocks.module('addaccounttest');
|
||||
mocks.inject(function($controller, $rootScope) {
|
||||
scope = $rootScope.$new();
|
||||
scope.state = {};
|
||||
ctrl = $controller(AddAccountCtrl, {
|
||||
$location: location,
|
||||
$scope: scope
|
||||
});
|
||||
});
|
||||
|
||||
scope.onError = function(err) {
|
||||
expect(err).to.equal(42);
|
||||
expect(fetchOAuthTokenStub.calledOnce).to.be.true;
|
||||
done();
|
||||
};
|
||||
fetchOAuthTokenStub.yields(42);
|
||||
|
||||
scope.connectToGoogle();
|
||||
});
|
||||
|
||||
it('should forward to login', function(done) {
|
||||
angular.module('addaccounttest', []);
|
||||
mocks.module('addaccounttest');
|
||||
mocks.inject(function($controller, $rootScope, $location) {
|
||||
location = $location;
|
||||
sinon.stub(location, 'path', function(path) {
|
||||
expect(path).to.equal('/login');
|
||||
expect(fetchOAuthTokenStub.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
scope = $rootScope.$new();
|
||||
scope.state = {};
|
||||
ctrl = $controller(AddAccountCtrl, {
|
||||
$location: location,
|
||||
$scope: scope
|
||||
});
|
||||
});
|
||||
|
||||
fetchOAuthTokenStub.yields();
|
||||
|
||||
scope.connectToGoogle();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -177,34 +177,6 @@ define(function(require) {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due to error in fetchOAuthToken', function(done) {
|
||||
appConfigStoreStub.listItems.yields(null, []);
|
||||
isOnlineStub.returns(true);
|
||||
fetchOAuthTokenStub.yields({});
|
||||
|
||||
controller.getEmailAddress(function(err, emailAddress) {
|
||||
expect(err).to.exist;
|
||||
expect(emailAddress).to.not.exist;
|
||||
expect(fetchOAuthTokenStub.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail work when fetching oauth token', function(done) {
|
||||
appConfigStoreStub.listItems.yields(null, []);
|
||||
isOnlineStub.returns(true);
|
||||
fetchOAuthTokenStub.yields(null, {
|
||||
emailAddress: 'asfd@example.com'
|
||||
});
|
||||
|
||||
controller.getEmailAddress(function(err, emailAddress) {
|
||||
expect(err).to.not.exist;
|
||||
expect(emailAddress).to.equal('asfd@example.com');
|
||||
expect(fetchOAuthTokenStub.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchOAuthToken', function() {
|
||||
|
@ -39,6 +39,7 @@ function startTests() {
|
||||
'test/new-unit/keychain-dao-test',
|
||||
'test/new-unit/devicestorage-dao-test',
|
||||
'test/new-unit/dialog-ctrl-test',
|
||||
'test/new-unit/add-account-ctrl-test',
|
||||
'test/new-unit/account-ctrl-test',
|
||||
'test/new-unit/login-existing-ctrl-test',
|
||||
'test/new-unit/login-initial-ctrl-test',
|
||||
|
Loading…
Reference in New Issue
Block a user