2fa login fixes for duo on safari

This commit is contained in:
Kyle Spearrin 2018-01-18 16:17:58 -05:00
parent 35385b8c98
commit 43f563d187
9 changed files with 77 additions and 14 deletions

View File

@ -31,10 +31,17 @@ document.addEventListener('DOMContentLoaded', () => {
sigValue: sigElement.value, sigValue: sigElement.value,
}, },
}); });
window.close();
} }
}, },
}); });
} else if (msg.data.type === 'success') {
safari.self.tab.dispatchMessage('bitwarden', {
command: 'openPopup',
});
setTimeout(() => {
window.close();
}, 500);
} else { } else {
// TODO: others like u2f? // TODO: others like u2f?
} }

View File

@ -3,9 +3,29 @@
<head> <head>
<title>Two-step Login</title> <title>Two-step Login</title>
<meta charset="utf-8" /> <meta charset="utf-8" />
<style>
html, body {
height: 90%;
padding: 0;
}
.frameWrapper {
background: url('../popup/images/loading.svg') 0 0 no-repeat;
width: 100%;
height: 100%;
margin-bottom: -10px;
}
.frameWrapper iframe {
width: 100%;
height: 100%;
border: none;
}
</style>
</head> </head>
<body style="padding: 30px; text-align: center; font-family: Arial; font-size: 18px;"> <body>
<div id="loading-message">Loading...</div> <div class="frameWrapper">
<iframe id="duo_iframe"></iframe> <iframe id="duo_iframe"></iframe>
</div>
</body> </body>
</html> </html>

View File

@ -93,12 +93,11 @@ export default class CommandsBackground {
private async openPopup() { private async openPopup() {
// Chrome APIs cannot open popup // Chrome APIs cannot open popup
if (!this.isSafari || !safari.extension.toolbarItems || !safari.extension.toolbarItems.length) { if (!this.isSafari) {
return; return;
} }
safari.extension.toolbarItems[0].showPopover(); this.main.openPopup();
(window as any).ga('send', { (window as any).ga('send', {
hitType: 'event', hitType: 'event',
eventAction: 'Opened Popup From Command', eventAction: 'Opened Popup From Command',

View File

@ -282,6 +282,21 @@ export default class MainBackground {
this.runtimeBackground.processMessage(message, { tab: null }, () => { /* No response needed. */ }); this.runtimeBackground.processMessage(message, { tab: null }, () => { /* No response needed. */ });
} }
async openPopup() {
// Chrome APIs cannot open popup
if (!this.isSafari || !safari.extension.toolbarItems || !safari.extension.toolbarItems.length) {
return;
}
const activeToolBars = safari.extension.toolbarItems.filter((tb: any) => {
return tb.browserWindow === safari.application.activeBrowserWindow;
});
if (activeToolBars && activeToolBars.length) {
activeToolBars[0].showPopover();
}
}
private async buildContextMenu() { private async buildContextMenu() {
if (this.isSafari || !chrome.contextMenus || this.buildingContextMenu) { if (this.isSafari || !chrome.contextMenus || this.buildingContextMenu) {
return; return;

View File

@ -81,6 +81,9 @@ export default class RuntimeBackground {
setTimeout(async () => await this.main.refreshBadgeAndMenu(), 2000); setTimeout(async () => await this.main.refreshBadgeAndMenu(), 2000);
} }
break; break;
case 'openPopup':
await this.main.openPopup();
break;
case 'bgGetDataForTab': case 'bgGetDataForTab':
await this.getDataForTab(sender.tab, msg.responseCommand); await this.getDataForTab(sender.tab, msg.responseCommand);
break; break;

View File

@ -9,6 +9,7 @@ angular
}, 500); }, 500);
$scope.i18n = i18nService; $scope.i18n = i18nService;
$scope.showNewWindowMessage = platformUtilsService.isSafari();
var customWebVaultUrl = null; var customWebVaultUrl = null;
if (environmentService.baseUrl) { if (environmentService.baseUrl) {
@ -54,7 +55,7 @@ angular
init(); init();
$scope.loginPromise = null; $scope.loginPromise = null;
$scope.login = function (token) { $scope.login = function (token, sendSuccessToTab) {
if (!token) { if (!token) {
toastr.error(i18nService.verificationCodeRequired, i18nService.errorsOccurred); toastr.error(i18nService.verificationCodeRequired, i18nService.errorsOccurred);
return; return;
@ -76,7 +77,18 @@ angular
$scope.loginPromise = authService.logIn(email, masterPassword, $scope.providerType, token, $scope.remember.checked); $scope.loginPromise = authService.logIn(email, masterPassword, $scope.providerType, token, $scope.remember.checked);
$scope.loginPromise.then(function () { $scope.loginPromise.then(function () {
$analytics.eventTrack('Logged In From Two-step'); $analytics.eventTrack('Logged In From Two-step');
$state.go('tabs.vault', { animation: 'in-slide-left', syncOnLoad: true }); $state.go('tabs.vault', { animation: 'in-slide-left', syncOnLoad: true }).then(function(){
if (sendSuccessToTab) {
$timeout(function() {
BrowserApi.tabSendMessage(sendSuccessToTab, {
command: '2faPageData',
data: {
type: 'success'
}
});
}, 1000);
}
});
}, function () { }, function () {
u2f.start(); u2f.start();
}); });
@ -126,7 +138,7 @@ angular
console.log('got 2fa response'); console.log('got 2fa response');
console.log(details); console.log(details);
if (details.type === 'duo') { if (details.type === 'duo') {
$scope.login(details.data.sigValue); $scope.login(details.data.sigValue, details.tab);
} }
}); });
@ -174,7 +186,7 @@ angular
signature: params.Signature signature: params.Signature
} }
}); });
}, 1000); }, 500);
} }
else { else {
$window.Duo.init({ $window.Duo.init({

View File

@ -52,9 +52,12 @@
<div class="title">Duo</div> <div class="title">Duo</div>
</div> </div>
<div class="content"> <div class="content">
<div id="duoFrameWrapper"> <div id="duoFrameWrapper" ng-if="!showNewWindowMessage">
<iframe id="duo_iframe"></iframe> <iframe id="duo_iframe"></iframe>
</div> </div>
<div ng-if="showNewWindowMessage">
<div class="two-step-window-message">Complete your two-step login request using the new window.</div>
</div>
<div class="list"> <div class="list">
<div class="list-section"> <div class="list-section">
<div class="list-section-items"> <div class="list-section-items">

View File

@ -26,8 +26,6 @@ export class MainController implements ng.IController {
}); });
$window.bitwardenPopupMainMessageListener = (msg: any, sender: any, sendResponse: any) => { $window.bitwardenPopupMainMessageListener = (msg: any, sender: any, sendResponse: any) => {
console.log(msg);
if (msg.command === 'syncCompleted') { if (msg.command === 'syncCompleted') {
$scope.$broadcast('syncCompleted', msg.successfully); $scope.$broadcast('syncCompleted', msg.successfully);
} else if (msg.command === 'syncStarted') { } else if (msg.command === 'syncStarted') {
@ -51,6 +49,7 @@ export class MainController implements ng.IController {
$scope.$broadcast('2faPageResponse', { $scope.$broadcast('2faPageResponse', {
type: msg.type, type: msg.type,
data: msg.data, data: msg.data,
tab: sender.tab,
}); });
} }
}; };

View File

@ -587,6 +587,11 @@
} }
} }
.two-step-window-message {
text-align: center;
margin: 30px 0 20px 0;
}
#duoFrameWrapper { #duoFrameWrapper {
background: ~"url('../images/loading.svg') 0 0 no-repeat"; background: ~"url('../images/loading.svg') 0 0 no-repeat";
width: 100%; width: 100%;