1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-12-22 16:29:09 +01:00

sweet alert dialog implementation

This commit is contained in:
Kyle Spearrin 2018-04-10 14:20:03 -04:00
parent e4a50cbbb0
commit 98b852287d
12 changed files with 109 additions and 38 deletions

2
jslib

@ -1 +1 @@
Subproject commit f8d8ca225360a0ed05f54642ed89da282d8a1021
Subproject commit fa5f6c09068add3951889961f545e6990d9c3ea7

24
package-lock.json generated
View File

@ -3637,6 +3637,12 @@
"event-emitter": "0.3.5"
}
},
"es6-object-assign": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
"integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=",
"dev": true
},
"es6-promise": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
@ -10945,6 +10951,12 @@
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
"dev": true
},
"promise-polyfill": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz",
"integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc=",
"dev": true
},
"proto-list": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
@ -13009,10 +13021,14 @@
}
},
"sweetalert": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-1.1.3.tgz",
"integrity": "sha1-0sMepJKyK2qNiHrqFZiaI4/AhK4=",
"dev": true
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.0.tgz",
"integrity": "sha512-9YKj0SvjKyBfRWco50UOsIbXVeifYbxzT9Qda7EsqC01eafHGCSG0IR7g942ufjzt7lnwO8ZZBwr6emXv2fQrg==",
"dev": true,
"requires": {
"es6-object-assign": "1.1.0",
"promise-polyfill": "6.1.0"
}
},
"symbol-observable": {
"version": "1.0.1",

View File

@ -79,7 +79,7 @@
"papaparse": "4.3.5",
"sass-loader": "^6.0.6",
"style-loader": "^0.19.0",
"sweetalert": "1.1.3",
"sweetalert": "2.1.0",
"tldjs": "2.0.0",
"ts-loader": "^3.5.0",
"tslint": "^5.9.1",

View File

@ -115,9 +115,9 @@ export default class MainBackground {
constructor() {
// Services
this.utilsService = new UtilsService();
this.platformUtilsService = new BrowserPlatformUtilsService();
this.messagingService = new BrowserMessagingService();
this.platformUtilsService = new BrowserPlatformUtilsService(this.messagingService);
const delayi18nLoad = this.platformUtilsService.isEdge() || this.platformUtilsService.isSafari() ? 1000 : 0;
this.messagingService = new BrowserMessagingService(this.platformUtilsService);
this.storageService = new BrowserStorageService(this.platformUtilsService, false);
this.secureStorageService = new BrowserStorageService(this.platformUtilsService, true);
this.i18nService = i18nService(this.platformUtilsService);
@ -161,7 +161,8 @@ export default class MainBackground {
// Background
this.runtimeBackground = new RuntimeBackground(this, this.autofillService, this.cipherService,
this.platformUtilsService, this.storageService, this.i18nService, this.analytics);
this.platformUtilsService as BrowserPlatformUtilsService, this.storageService, this.i18nService,
this.analytics);
this.tabsBackground = new TabsBackground(this, this.platformUtilsService);
this.commandsBackground = new CommandsBackground(this, this.passwordGenerationService,
this.platformUtilsService, this.analytics);

View File

@ -11,7 +11,6 @@ import { Analytics } from 'jslib/misc';
import {
CipherService,
PlatformUtilsService,
StorageService,
} from 'jslib/abstractions';
@ -20,6 +19,7 @@ import { BrowserApi } from '../browser/browserApi';
import MainBackground from './main.background';
import { AutofillService } from '../services/abstractions/autofill.service';
import BrowserPlatformUtilsService from '../services/browserPlatformUtils.service';
export default class RuntimeBackground {
private runtime: any;
@ -29,7 +29,7 @@ export default class RuntimeBackground {
private onInstalledReason: string = null;
constructor(private main: MainBackground, private autofillService: AutofillService,
private cipherService: CipherService, private platformUtilsService: PlatformUtilsService,
private cipherService: CipherService, private platformUtilsService: BrowserPlatformUtilsService,
private storageService: StorageService, private i18nService: any, private analytics: Analytics) {
this.isSafari = this.platformUtilsService.isSafari();
this.runtime = this.isSafari ? safari.application : chrome.runtime;
@ -90,6 +90,9 @@ export default class RuntimeBackground {
case 'openPopup':
await this.main.openPopup();
break;
case 'showDialogResolve':
this.platformUtilsService.resolveDialogPromise(msg.dialogId, msg.confirmed);
break;
case 'bgGetDataForTab':
await this.getDataForTab(sender.tab, msg.responseCommand);
break;

View File

@ -8,7 +8,7 @@ import { AuthService } from 'jslib/services/auth.service';
import BrowserMessagingService from '../../../services/browserMessaging.service';
const messagingService = new BrowserMessagingService(backgroundServices.platformUtilsService());
const messagingService = new BrowserMessagingService();
const authService = new AuthService(backgroundServices.cryptoService(), backgroundServices.apiService(),
backgroundServices.userService(), backgroundServices.tokenService(), backgroundServices.appIdService(),
backgroundServices.i18n2Service(), backgroundServices.platformUtilsService(),

View File

@ -3,6 +3,7 @@ import {
ToasterContainerComponent,
} from 'angular2-toaster';
import { Angulartics2GoogleAnalytics } from 'angulartics2/ga';
import swal from 'sweetalert';
import {
Component,
@ -23,6 +24,7 @@ import { BroadcasterService } from 'jslib/angular/services/broadcaster.service';
import { AuthService } from 'jslib/abstractions/auth.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { MessagingService } from 'jslib/abstractions/messaging.service';
import { StateService } from 'jslib/abstractions/state.service';
import { StorageService } from 'jslib/abstractions/storage.service';
@ -57,7 +59,7 @@ export class AppComponent implements OnInit {
private toasterService: ToasterService, private storageService: StorageService,
private broadcasterService: BroadcasterService, private authService: AuthService,
private i18nService: I18nService, private router: Router,
private stateService: StateService) { }
private stateService: StateService, private messagingService: MessagingService) { }
ngOnInit() {
window.onmousemove = () => this.recordActivity();
@ -67,7 +69,7 @@ export class AppComponent implements OnInit {
window.onscroll = () => this.recordActivity();
window.onkeypress = () => this.recordActivity();
(window as any).bitwardenPopupMainMessageListener = (msg: any, sender: any, sendResponse: any) => {
(window as any).bitwardenPopupMainMessageListener = async (msg: any, sender: any, sendResponse: any) => {
if (msg.command === 'doneLoggingOut') {
this.authService.logOut(() => {
this.analytics.eventTrack.next({ action: 'Logged Out' });
@ -77,6 +79,22 @@ export class AppComponent implements OnInit {
}
this.router.navigate(['home']);
});
} else if (msg.command === 'showDialog') {
const buttons = [msg.confirmText == null ? this.i18nService.t('ok') : msg.confirmText];
if (msg.cancelText != null) {
buttons.unshift(msg.cancelText);
}
const confirmed = await swal({
title: msg.title,
text: msg.text,
buttons: buttons,
});
this.messagingService.send('showDialogResolve', {
dialogId: msg.dialogId,
confirmed: confirmed,
});
} else {
msg.webExtSender = sender;
this.broadcasterService.send(msg);

View File

@ -51,7 +51,7 @@ function getBgService<T>(service: string) {
}
export const stateService = new StateService();
export const messagingService = new BrowserMessagingService(getBgService<PlatformUtilsService>('platformUtilsService')());
export const messagingService = new BrowserMessagingService();
export const authService = new AuthService(getBgService<CryptoService>('cryptoService')(),
getBgService<ApiService>('apiService')(), getBgService<UserService>('userService')(),
getBgService<TokenService>('tokenService')(), getBgService<AppIdService>('appIdService')(),

View File

@ -87,9 +87,12 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit {
this.location.back();
}
async generatePassword() {
await super.generatePassword();
this.stateService.save('addEditCipher', this.cipher);
this.router.navigate(['generator']);
async generatePassword(): Promise<boolean> {
const confirmed = await super.generatePassword();
if (confirmed) {
this.stateService.save('addEditCipher', this.cipher);
this.router.navigate(['generator']);
}
return confirmed;
}
}

View File

@ -1,18 +1,12 @@
import { BrowserApi } from '../browser/browserApi';
import {
MessagingService,
PlatformUtilsService,
} from 'jslib/abstractions';
import { MessagingService } from 'jslib/abstractions';
export default class BrowserMessagingService implements MessagingService {
constructor(private platformUtilsService: PlatformUtilsService) {
}
send(subscriber: string, arg: any = {}) {
const message = Object.assign({}, { command: subscriber }, arg);
if (this.platformUtilsService.isSafari()) {
if (BrowserApi.isSafariApi) {
const bgPage = BrowserApi.getBackgroundPage();
bgPage.bitwardenMain.sendInternalRuntimeMessage(message);

View File

@ -48,7 +48,7 @@ describe('Browser Utils Service', () => {
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'
});
const browserPlatformUtilsService = new BrowserPlatformUtilsService();
const browserPlatformUtilsService = new BrowserPlatformUtilsService(null);
expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.Chrome);
});
@ -58,7 +58,7 @@ describe('Browser Utils Service', () => {
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0'
});
const browserPlatformUtilsService = new BrowserPlatformUtilsService();
const browserPlatformUtilsService = new BrowserPlatformUtilsService(null);
expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.Firefox);
});
@ -68,7 +68,7 @@ describe('Browser Utils Service', () => {
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3175.3 Safari/537.36 OPR/49.0.2695.0 (Edition developer)'
});
const browserPlatformUtilsService = new BrowserPlatformUtilsService();
const browserPlatformUtilsService = new BrowserPlatformUtilsService(null);
expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.Opera);
});
@ -78,7 +78,7 @@ describe('Browser Utils Service', () => {
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; ServiceUI 9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063'
});
const browserPlatformUtilsService = new BrowserPlatformUtilsService();
const browserPlatformUtilsService = new BrowserPlatformUtilsService(null);
expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.Edge);
});
@ -88,7 +88,7 @@ describe('Browser Utils Service', () => {
value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8'
});
const browserPlatformUtilsService = new BrowserPlatformUtilsService();
const browserPlatformUtilsService = new BrowserPlatformUtilsService(null);
expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.Safari);
});
@ -98,7 +98,7 @@ describe('Browser Utils Service', () => {
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.97 Safari/537.36 Vivaldi/1.94.1008.40'
});
const browserPlatformUtilsService = new BrowserPlatformUtilsService();
const browserPlatformUtilsService = new BrowserPlatformUtilsService(null);
expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.Vivaldi);
});
});

View File

@ -2,11 +2,12 @@ import * as tldjs from 'tldjs';
import { BrowserApi } from '../browser/browserApi';
import { DeviceType } from 'jslib/enums';
import { DeviceType } from 'jslib/enums/deviceType';
import { PlatformUtilsService } from 'jslib/abstractions';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { MessagingService } from 'jslib/abstractions/messaging.service';
import { UtilsService } from 'jslib/services';
import { UtilsService } from 'jslib/services/utils.service';
const AnalyticsIds = {
[DeviceType.Chrome]: 'UA-81915606-6',
@ -17,6 +18,8 @@ const AnalyticsIds = {
[DeviceType.Safari]: 'UA-81915606-16',
};
const DialogPromiseExpiration = 3600000; // 1 hour
export default class BrowserPlatformUtilsService implements PlatformUtilsService {
static getDomain(uriString: string): string {
if (uriString == null) {
@ -57,9 +60,12 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
identityClientId: string = 'browser';
private showDialogResolves = new Map<number, { resolve: (value: boolean) => void, date: Date }>();
private deviceCache: DeviceType = null;
private analyticsIdCache: string = null;
constructor(private messagingService: MessagingService) { }
getDevice(): DeviceType {
if (this.deviceCache) {
return this.deviceCache;
@ -169,8 +175,18 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
}
showDialog(text: string, title?: string, confirmText?: string, cancelText?: string, type?: string) {
// TODO
return Promise.resolve(true);
const dialogId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
this.messagingService.send('showDialog', {
text: text,
title: title,
confirmText: confirmText,
cancelText: cancelText,
type: type,
dialogId: dialogId,
});
return new Promise<boolean>((resolve) => {
this.showDialogResolves.set(dialogId, { resolve: resolve, date: new Date() });
});
}
isDev(): boolean {
@ -183,6 +199,26 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
UtilsService.copyToClipboard(text, doc);
}
resolveDialogPromise(dialogId: number, confirmed: boolean) {
if (this.showDialogResolves.has(dialogId)) {
const resolveObj = this.showDialogResolves.get(dialogId);
resolveObj.resolve(confirmed);
this.showDialogResolves.delete(dialogId);
}
// Clean up old promises
const deleteIds: number[] = [];
this.showDialogResolves.forEach((val, key) => {
const age = new Date().getTime() - val.date.getTime();
if (age > DialogPromiseExpiration) {
deleteIds.push(key);
}
});
deleteIds.forEach((id) => {
this.showDialogResolves.delete(id);
});
}
private sidebarViewName(): string {
if ((window as any).chrome.sidebarAction && this.isFirefox()) {
return 'sidebar';