bitwarden-estensione-browser/src/popup/app.component.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

255 lines
8.6 KiB
TypeScript
Raw Normal View History

2018-04-04 04:14:54 +02:00
import { ChangeDetectorRef, Component, NgZone, OnInit, SecurityContext } from "@angular/core";
2018-10-03 05:33:56 +02:00
import { DomSanitizer } from "@angular/platform-browser";
2018-04-09 15:51:22 +02:00
import { NavigationEnd, Router, RouterOutlet } from "@angular/router";
2021-12-07 20:42:18 +01:00
import { IndividualConfig, ToastrService } from "ngx-toastr";
import Swal, { SweetAlertIcon } from "sweetalert2/src/sweetalert2.js";
import { BrowserApi } from "../browser/browserApi";
2021-12-21 15:43:35 +01:00
import { AuthService } from "jslib-common/abstractions/auth.service";
2021-12-06 12:21:07 +01:00
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
import { I18nService } from "jslib-common/abstractions/i18n.service";
import { KeyConnectorService } from "jslib-common/abstractions/keyConnector.service";
import { MessagingService } from "jslib-common/abstractions/messaging.service";
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
import { StateService } from "jslib-common/abstractions/state.service";
import { StorageService } from "jslib-common/abstractions/storage.service";
2021-12-21 15:43:35 +01:00
import { ConstantsService } from "jslib-common/services/constants.service";
2021-12-21 15:43:35 +01:00
2018-04-08 06:30:04 +02:00
import { routerTransition } from "./app-routing.animations";
2018-04-04 04:14:54 +02:00
@Component({
selector: "app-root",
styles: [],
2018-04-08 06:30:04 +02:00
animations: [routerTransition],
template: ` <main [@routerTransition]="getState(o)">
<router-outlet #o="outlet"></router-outlet>
</main>`,
2018-04-04 04:14:54 +02:00
})
2018-04-06 21:33:20 +02:00
export class AppComponent implements OnInit {
private lastActivity: number = null;
2021-12-21 15:43:35 +01:00
2021-12-07 20:42:18 +01:00
constructor(
private toastrService: ToastrService,
private storageService: StorageService,
2018-04-06 21:33:20 +02:00
private broadcasterService: BroadcasterService,
private authService: AuthService,
2018-04-09 20:17:58 +02:00
private i18nService: I18nService,
private router: Router,
2018-04-10 23:14:10 +02:00
private stateService: StateService,
private messagingService: MessagingService,
2018-10-03 05:33:56 +02:00
private changeDetectorRef: ChangeDetectorRef,
private ngZone: NgZone,
private sanitizer: DomSanitizer,
private platformUtilsService: PlatformUtilsService,
private keyConnectoService: KeyConnectorService
2021-12-21 15:43:35 +01:00
) {}
2018-04-06 21:33:20 +02:00
ngOnInit() {
2018-04-14 04:08:24 +02:00
if (BrowserApi.getBackgroundPage() == null) {
2021-12-21 15:43:35 +01:00
return;
}
2018-04-04 04:14:54 +02:00
2018-04-06 21:33:20 +02:00
this.ngZone.runOutsideAngular(() => {
window.onmousemove = () => this.recordActivity();
2018-04-12 20:24:42 +02:00
window.onmousedown = () => this.recordActivity();
2018-04-06 21:33:20 +02:00
window.ontouchstart = () => this.recordActivity();
2021-12-07 20:42:18 +01:00
window.onclick = () => this.recordActivity();
window.onscroll = () => this.recordActivity();
window.onkeypress = () => this.recordActivity();
2021-12-21 15:43:35 +01:00
});
2021-12-07 20:42:18 +01:00
(window as any).bitwardenPopupMainMessageListener = async (
msg: any,
sender: any,
2018-04-06 21:33:20 +02:00
sendResponse: any
2021-12-21 15:43:35 +01:00
) => {
2018-04-06 21:33:20 +02:00
if (msg.command === "doneLoggingOut") {
this.ngZone.run(async () => {
this.authService.logOut(() => {
2018-04-10 23:14:10 +02:00
if (msg.expired) {
2018-04-06 21:33:20 +02:00
this.showToast({
type: "warning",
2018-04-09 20:17:58 +02:00
title: this.i18nService.t("loggedOut"),
text: this.i18nService.t("loginExpired"),
2021-12-21 15:43:35 +01:00
});
}
2018-04-09 20:17:58 +02:00
this.router.navigate(["home"]);
2018-04-10 23:14:10 +02:00
this.stateService.purge();
2021-12-21 15:43:35 +01:00
});
2018-10-03 05:33:56 +02:00
this.changeDetectorRef.detectChanges();
2021-12-21 15:43:35 +01:00
});
} else if (msg.command === "authBlocked") {
2019-04-18 16:11:01 +02:00
this.ngZone.run(() => {
this.router.navigate(["home"]);
2021-12-21 15:43:35 +01:00
});
} else if (msg.command === "locked") {
this.stateService.purge();
2019-04-18 16:11:01 +02:00
this.ngZone.run(() => {
this.router.navigate(["lock"]);
2021-12-21 15:43:35 +01:00
});
2018-04-10 20:20:03 +02:00
} else if (msg.command === "showDialog") {
await this.showDialog(msg);
2018-10-03 05:33:56 +02:00
} else if (msg.command === "showToast") {
2018-10-03 15:51:14 +02:00
this.ngZone.run(() => {
this.showToast(msg);
2021-12-21 15:43:35 +01:00
});
} else if (msg.command === "reloadProcess") {
const windowReload =
this.platformUtilsService.isSafari() ||
this.platformUtilsService.isFirefox() ||
this.platformUtilsService.isOpera();
2018-04-14 04:08:24 +02:00
if (windowReload) {
// Wait to make sure background has reloaded first.
window.setTimeout(() => BrowserApi.reloadExtension(window), 2000);
}
2018-04-12 20:24:42 +02:00
} else if (msg.command === "reloadPopup") {
this.ngZone.run(() => {
this.router.navigate(["/"]);
});
2019-08-17 02:48:01 +02:00
} else if (msg.command === "convertAccountToKeyConnector") {
2018-10-03 15:51:14 +02:00
this.ngZone.run(async () => {
await this.keyConnectoService.setConvertAccountRequired(true);
this.router.navigate(["/remove-password"]);
2018-04-09 20:17:58 +02:00
});
2020-09-15 16:50:45 +02:00
} else {
msg.webExtSender = sender;
this.broadcasterService.send(msg);
2021-12-21 15:43:35 +01:00
}
};
BrowserApi.messageListener("app.component", (window as any).bitwardenPopupMainMessageListener);
2021-12-21 15:43:35 +01:00
this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd) {
const url = event.urlAfterRedirects || event.url || "";
2021-12-21 15:43:35 +01:00
if (
url.startsWith("/tabs/") &&
(window as any).previousPopupUrl != null &&
(window as any).previousPopupUrl.startsWith("/tabs/")
2021-12-21 15:43:35 +01:00
) {
this.stateService.remove("GroupingsComponent");
this.stateService.remove("GroupingsComponentScope");
2018-04-09 20:17:58 +02:00
this.stateService.remove("CiphersComponent");
this.stateService.remove("SendGroupingsComponent");
this.stateService.remove("SendGroupingsComponentScope");
this.stateService.remove("SendTypeComponent");
}
2018-04-06 21:33:20 +02:00
if (url.startsWith("/tabs/")) {
this.stateService.remove("addEditCipherInfo");
}
(window as any).previousPopupUrl = url;
2018-04-06 21:33:20 +02:00
// Clear route direction after animation (400ms)
2018-10-03 15:51:14 +02:00
if ((window as any).routeDirection != null) {
2021-12-07 20:42:18 +01:00
window.setTimeout(() => {
(window as any).routeDirection = null;
2018-10-03 05:33:56 +02:00
}, 400);
}
2021-12-21 15:43:35 +01:00
}
});
}
2018-10-03 05:33:56 +02:00
getState(outlet: RouterOutlet) {
if (outlet.activatedRouteData.state === "ciphers") {
2021-12-07 20:42:18 +01:00
const routeDirection =
2018-10-03 05:33:56 +02:00
(window as any).routeDirection != null ? (window as any).routeDirection : "";
2021-12-21 15:43:35 +01:00
return (
2021-12-07 20:42:18 +01:00
"ciphers_direction=" +
routeDirection +
2021-12-21 15:43:35 +01:00
"_" +
2021-12-07 20:42:18 +01:00
(outlet.activatedRoute.queryParams as any).value.folderId +
2021-12-21 15:43:35 +01:00
"_" +
2021-12-07 20:42:18 +01:00
(outlet.activatedRoute.queryParams as any).value.collectionId
);
} else {
return outlet.activatedRouteData.state;
2018-10-03 05:33:56 +02:00
}
2021-12-21 15:43:35 +01:00
}
2018-10-03 05:33:56 +02:00
2018-04-13 05:18:51 +02:00
private async recordActivity() {
const now = new Date().getTime();
if (this.lastActivity != null && now - this.lastActivity < 250) {
2018-04-13 05:18:51 +02:00
return;
}
this.lastActivity = now;
this.storageService.save(ConstantsService.lastActiveKey, now);
2021-12-21 15:43:35 +01:00
}
private showToast(msg: any) {
let message = "";
2021-12-21 15:43:35 +01:00
const options: Partial<IndividualConfig> = {};
2021-12-21 15:43:35 +01:00
if (typeof msg.text === "string") {
message = msg.text;
} else if (msg.text.length === 1) {
message = msg.text[0];
2021-12-21 15:43:35 +01:00
} else {
msg.text.forEach(
(t: string) =>
(message += "<p>" + this.sanitizer.sanitize(SecurityContext.HTML, t) + "</p>")
2021-12-21 15:43:35 +01:00
);
2021-12-07 20:42:18 +01:00
options.enableHtml = true;
2021-12-21 15:43:35 +01:00
}
2018-10-03 05:33:56 +02:00
if (msg.options != null) {
if (msg.options.trustedHtml === true) {
2021-12-07 20:42:18 +01:00
options.enableHtml = true;
2021-12-21 15:43:35 +01:00
}
if (msg.options.timeout != null && msg.options.timeout > 0) {
options.timeOut = msg.options.timeout;
2018-04-13 05:18:51 +02:00
}
2021-12-21 15:43:35 +01:00
}
2018-04-13 05:18:51 +02:00
this.toastrService.show(message, msg.title, options, "toast-" + msg.type);
2021-12-21 15:43:35 +01:00
}
2018-04-13 05:18:51 +02:00
private async showDialog(msg: any) {
let iconClasses: string = null;
const type = msg.type;
if (type != null) {
// If you add custom types to this part, the type to SweetAlertIcon cast below needs to be changed.
switch (type) {
2018-04-13 05:18:51 +02:00
case "success":
iconClasses = "fa-check text-success";
2021-12-21 15:43:35 +01:00
break;
case "warning":
iconClasses = "fa-warning text-warning";
2021-12-21 15:43:35 +01:00
break;
2018-04-13 05:18:51 +02:00
case "error":
iconClasses = "fa-bolt text-danger";
2021-12-21 15:43:35 +01:00
break;
case "info":
iconClasses = "fa-info-circle text-info";
2018-04-13 05:18:51 +02:00
break;
2021-12-21 15:43:35 +01:00
default:
break;
2018-04-13 05:18:51 +02:00
}
}
2021-12-21 15:43:35 +01:00
const cancelText = msg.cancelText;
const confirmText = msg.confirmText;
const confirmed = await Swal.fire({
heightAuto: false,
buttonsStyling: false,
icon: type as SweetAlertIcon, // required to be any of the SweetAlertIcons to output the iconHtml.
iconHtml:
iconClasses != null ? `<i class="swal-custom-icon fa ${iconClasses}"></i>` : undefined,
text: msg.text,
2020-10-19 16:50:25 +02:00
html: msg.html,
titleText: msg.title,
showCancelButton: cancelText != null,
cancelButtonText: cancelText,
showConfirmButton: true,
confirmButtonText: confirmText == null ? this.i18nService.t("ok") : confirmText,
timer: 300000,
2021-12-21 15:43:35 +01:00
});
this.messagingService.send("showDialogResolve", {
2018-04-13 05:18:51 +02:00
dialogId: msg.dialogId,
confirmed: confirmed.value,
2021-12-21 15:43:35 +01:00
});
}
2018-04-04 04:14:54 +02:00
}