2018-04-05 04:59:42 +02:00
|
|
|
import { ChangeDetectorRef, Component, NgZone, OnDestroy, OnInit } from "@angular/core";
|
2019-08-19 15:31:05 +02:00
|
|
|
import { Router } from "@angular/router";
|
2019-08-19 15:17:40 +02:00
|
|
|
|
2021-12-06 12:21:07 +01:00
|
|
|
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
|
2021-06-07 19:25:37 +02:00
|
|
|
import { CipherService } from "jslib-common/abstractions/cipher.service";
|
|
|
|
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
2022-05-09 14:19:18 +02:00
|
|
|
import { OrganizationService } from "jslib-common/abstractions/organization.service";
|
2021-06-07 19:25:37 +02:00
|
|
|
import { PasswordRepromptService } from "jslib-common/abstractions/passwordReprompt.service";
|
|
|
|
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
|
|
|
|
import { SearchService } from "jslib-common/abstractions/search.service";
|
2022-01-27 22:22:51 +01:00
|
|
|
import { StateService } from "jslib-common/abstractions/state.service";
|
2021-06-07 19:25:37 +02:00
|
|
|
import { SyncService } from "jslib-common/abstractions/sync.service";
|
2022-02-24 18:14:04 +01:00
|
|
|
import { CipherRepromptType } from "jslib-common/enums/cipherRepromptType";
|
|
|
|
import { CipherType } from "jslib-common/enums/cipherType";
|
|
|
|
import { Utils } from "jslib-common/misc/utils";
|
|
|
|
import { CipherView } from "jslib-common/models/view/cipherView";
|
2018-04-06 20:03:35 +02:00
|
|
|
|
2022-02-24 18:14:04 +01:00
|
|
|
import { BrowserApi } from "../../browser/browserApi";
|
2018-04-06 20:03:35 +02:00
|
|
|
import { AutofillService } from "../../services/abstractions/autofill.service";
|
2022-05-09 14:19:18 +02:00
|
|
|
import { VaultFilterService } from "../../services/vaultFilter.service";
|
2018-04-06 20:03:35 +02:00
|
|
|
import { PopupUtilsService } from "../services/popup-utils.service";
|
2018-04-06 21:33:20 +02:00
|
|
|
|
|
|
|
const BroadcasterSubscriptionId = "CurrentTabComponent";
|
2018-04-06 20:03:35 +02:00
|
|
|
|
2018-04-05 04:59:42 +02:00
|
|
|
@Component({
|
2018-04-06 20:03:35 +02:00
|
|
|
selector: "app-current-tab",
|
|
|
|
templateUrl: "current-tab.component.html",
|
2018-04-05 04:59:42 +02:00
|
|
|
})
|
2018-04-06 21:33:20 +02:00
|
|
|
export class CurrentTabComponent implements OnInit, OnDestroy {
|
2018-04-06 20:03:35 +02:00
|
|
|
pageDetails: any[] = [];
|
2018-04-06 20:18:28 +02:00
|
|
|
cardCiphers: CipherView[];
|
|
|
|
identityCiphers: CipherView[];
|
|
|
|
loginCiphers: CipherView[];
|
2018-04-06 20:03:35 +02:00
|
|
|
url: string;
|
2018-04-15 03:12:04 +02:00
|
|
|
hostname: string;
|
2018-04-09 16:50:28 +02:00
|
|
|
searchText: string;
|
2018-04-06 20:03:35 +02:00
|
|
|
inSidebar = false;
|
2019-03-14 03:54:18 +01:00
|
|
|
searchTypeSearch = false;
|
2018-04-06 20:03:35 +02:00
|
|
|
loaded = false;
|
2022-05-09 14:19:18 +02:00
|
|
|
showOrganizations = false;
|
2021-12-21 15:43:35 +01:00
|
|
|
|
2018-04-23 17:30:12 +02:00
|
|
|
private totpCode: string;
|
|
|
|
private totpTimeout: number;
|
|
|
|
private loadedTimeout: number;
|
2018-08-13 17:53:16 +02:00
|
|
|
private searchTimeout: number;
|
2021-12-21 15:43:35 +01:00
|
|
|
|
2018-04-06 20:03:35 +02:00
|
|
|
constructor(
|
|
|
|
private platformUtilsService: PlatformUtilsService,
|
|
|
|
private cipherService: CipherService,
|
|
|
|
private popupUtilsService: PopupUtilsService,
|
|
|
|
private autofillService: AutofillService,
|
2021-12-07 20:42:18 +01:00
|
|
|
private i18nService: I18nService,
|
|
|
|
private router: Router,
|
2018-04-06 21:33:20 +02:00
|
|
|
private ngZone: NgZone,
|
|
|
|
private broadcasterService: BroadcasterService,
|
2018-08-13 17:53:16 +02:00
|
|
|
private changeDetectorRef: ChangeDetectorRef,
|
|
|
|
private syncService: SyncService,
|
2021-05-03 20:56:38 +02:00
|
|
|
private searchService: SearchService,
|
2022-01-27 22:22:51 +01:00
|
|
|
private stateService: StateService,
|
2022-05-09 14:19:18 +02:00
|
|
|
private passwordRepromptService: PasswordRepromptService,
|
|
|
|
private organizationService: OrganizationService,
|
|
|
|
private vaultFilterService: VaultFilterService
|
2021-12-21 15:43:35 +01:00
|
|
|
) {}
|
|
|
|
|
2019-08-19 15:31:05 +02:00
|
|
|
async ngOnInit() {
|
|
|
|
this.searchTypeSearch = !this.platformUtilsService.isSafari();
|
|
|
|
this.inSidebar = this.popupUtilsService.inSidebar(window);
|
2021-12-21 15:43:35 +01:00
|
|
|
|
2019-08-19 15:31:05 +02:00
|
|
|
this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {
|
|
|
|
this.ngZone.run(async () => {
|
|
|
|
switch (message.command) {
|
|
|
|
case "syncCompleted":
|
|
|
|
if (this.loaded) {
|
|
|
|
window.setTimeout(() => {
|
|
|
|
this.load();
|
2021-12-21 15:43:35 +01:00
|
|
|
}, 500);
|
2019-08-19 15:31:05 +02:00
|
|
|
}
|
2021-12-21 15:43:35 +01:00
|
|
|
break;
|
2019-08-19 15:31:05 +02:00
|
|
|
case "collectPageDetailsResponse":
|
|
|
|
if (message.sender === BroadcasterSubscriptionId) {
|
|
|
|
this.pageDetails.push({
|
|
|
|
frameId: message.webExtSender.frameId,
|
|
|
|
tab: message.tab,
|
|
|
|
details: message.details,
|
|
|
|
});
|
2021-12-21 15:43:35 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2019-08-19 15:31:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
this.changeDetectorRef.detectChanges();
|
|
|
|
});
|
2018-04-06 20:03:35 +02:00
|
|
|
});
|
|
|
|
|
2018-04-06 21:33:20 +02:00
|
|
|
if (!this.syncService.syncInProgress) {
|
2018-04-11 04:49:19 +02:00
|
|
|
await this.load();
|
2021-12-21 15:43:35 +01:00
|
|
|
} else {
|
2018-04-11 04:49:19 +02:00
|
|
|
this.loadedTimeout = window.setTimeout(async () => {
|
2018-04-06 21:33:20 +02:00
|
|
|
if (!this.loaded) {
|
|
|
|
await this.load();
|
2021-12-21 15:43:35 +01:00
|
|
|
}
|
|
|
|
}, 5000);
|
2018-04-06 21:33:20 +02:00
|
|
|
}
|
|
|
|
|
2019-08-19 15:31:05 +02:00
|
|
|
window.setTimeout(() => {
|
|
|
|
document.getElementById("search").focus();
|
2021-12-21 15:43:35 +01:00
|
|
|
}, 100);
|
|
|
|
}
|
|
|
|
|
2018-04-06 21:33:20 +02:00
|
|
|
ngOnDestroy() {
|
2018-04-23 17:30:12 +02:00
|
|
|
window.clearTimeout(this.loadedTimeout);
|
2018-04-06 21:33:20 +02:00
|
|
|
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
|
2021-12-21 15:43:35 +01:00
|
|
|
}
|
|
|
|
|
2018-04-06 20:03:35 +02:00
|
|
|
async refresh() {
|
|
|
|
await this.load();
|
2021-12-21 15:43:35 +01:00
|
|
|
}
|
|
|
|
|
2018-04-06 20:03:35 +02:00
|
|
|
addCipher() {
|
2022-05-17 23:03:57 +02:00
|
|
|
this.router.navigate(["/add-cipher"], {
|
|
|
|
queryParams: {
|
|
|
|
name: this.hostname,
|
|
|
|
uri: this.url,
|
|
|
|
selectedVault: this.vaultFilterService.getVaultFilter().selectedOrganizationId,
|
|
|
|
},
|
|
|
|
});
|
2021-12-21 15:43:35 +01:00
|
|
|
}
|
|
|
|
|
2018-04-06 20:03:35 +02:00
|
|
|
viewCipher(cipher: CipherView) {
|
|
|
|
this.router.navigate(["/view-cipher"], { queryParams: { cipherId: cipher.id } });
|
2021-12-21 15:43:35 +01:00
|
|
|
}
|
|
|
|
|
2019-08-19 15:38:59 +02:00
|
|
|
async fillCipher(cipher: CipherView) {
|
2021-12-21 15:43:35 +01:00
|
|
|
if (
|
2021-05-03 20:56:38 +02:00
|
|
|
cipher.reprompt !== CipherRepromptType.None &&
|
|
|
|
!(await this.passwordRepromptService.showPasswordPrompt())
|
2021-12-21 15:43:35 +01:00
|
|
|
) {
|
|
|
|
return;
|
2018-04-06 20:03:35 +02:00
|
|
|
}
|
|
|
|
|
2018-04-15 03:12:04 +02:00
|
|
|
this.totpCode = null;
|
|
|
|
if (this.totpTimeout != null) {
|
|
|
|
window.clearTimeout(this.totpTimeout);
|
2018-04-06 20:03:35 +02:00
|
|
|
}
|
2018-04-05 04:59:42 +02:00
|
|
|
|
2018-04-06 20:03:35 +02:00
|
|
|
if (this.pageDetails == null || this.pageDetails.length === 0) {
|
|
|
|
this.platformUtilsService.showToast("error", null, this.i18nService.t("autofillError"));
|
2021-12-21 15:43:35 +01:00
|
|
|
return;
|
2018-04-05 04:59:42 +02:00
|
|
|
}
|
2018-04-06 20:03:35 +02:00
|
|
|
|
2021-05-03 20:56:38 +02:00
|
|
|
try {
|
2021-12-07 20:42:18 +01:00
|
|
|
this.totpCode = await this.autofillService.doAutoFill({
|
|
|
|
cipher: cipher,
|
2019-08-19 15:38:59 +02:00
|
|
|
pageDetails: this.pageDetails,
|
|
|
|
doc: window.document,
|
2020-09-21 21:41:06 +02:00
|
|
|
fillNewPassword: true,
|
2019-08-19 15:38:59 +02:00
|
|
|
});
|
2019-08-19 18:05:13 +02:00
|
|
|
if (this.totpCode != null) {
|
2019-08-19 15:38:59 +02:00
|
|
|
this.platformUtilsService.copyToClipboard(this.totpCode, { window: window });
|
2018-04-06 20:03:35 +02:00
|
|
|
}
|
|
|
|
if (this.popupUtilsService.inPopup(window)) {
|
2021-09-21 23:36:28 +02:00
|
|
|
if (this.platformUtilsService.isFirefox() || this.platformUtilsService.isSafari()) {
|
|
|
|
BrowserApi.closePopup(window);
|
|
|
|
} else {
|
|
|
|
// Slight delay to fix bug in Chromium browsers where popup closes without copying totp to clipboard
|
|
|
|
setTimeout(() => BrowserApi.closePopup(window), 50);
|
2019-08-19 15:38:59 +02:00
|
|
|
}
|
2021-12-21 15:43:35 +01:00
|
|
|
}
|
2019-08-19 15:38:59 +02:00
|
|
|
} catch {
|
2018-04-23 17:50:14 +02:00
|
|
|
this.ngZone.run(() => {
|
2021-12-07 20:42:18 +01:00
|
|
|
this.platformUtilsService.showToast("error", null, this.i18nService.t("autofillError"));
|
2018-04-23 17:50:14 +02:00
|
|
|
this.changeDetectorRef.detectChanges();
|
2021-12-21 15:43:35 +01:00
|
|
|
});
|
2018-04-06 20:03:35 +02:00
|
|
|
}
|
2021-12-21 15:43:35 +01:00
|
|
|
}
|
2018-04-06 20:03:35 +02:00
|
|
|
|
|
|
|
searchVault() {
|
2018-08-13 17:53:16 +02:00
|
|
|
if (this.searchTimeout != null) {
|
|
|
|
clearTimeout(this.searchTimeout);
|
2018-04-06 20:03:35 +02:00
|
|
|
}
|
2018-08-13 17:53:16 +02:00
|
|
|
if (!this.searchService.isSearchable(this.searchText)) {
|
2021-12-21 15:43:35 +01:00
|
|
|
return;
|
|
|
|
}
|
2018-08-13 17:53:16 +02:00
|
|
|
this.searchTimeout = window.setTimeout(async () => {
|
|
|
|
this.router.navigate(["/tabs/vault"], { queryParams: { searchText: this.searchText } });
|
2021-12-21 15:43:35 +01:00
|
|
|
}, 200);
|
|
|
|
}
|
|
|
|
|
2021-04-23 10:45:20 +02:00
|
|
|
closeOnEsc(e: KeyboardEvent) {
|
|
|
|
// If input not empty, use browser default behavior of clearing input instead
|
|
|
|
if (e.key === "Escape" && (this.searchText == null || this.searchText === "")) {
|
|
|
|
BrowserApi.closePopup(window);
|
2021-12-21 15:43:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-06 20:03:35 +02:00
|
|
|
private async load() {
|
2022-05-09 14:19:18 +02:00
|
|
|
this.loaded = false;
|
2018-04-06 20:03:35 +02:00
|
|
|
const tab = await BrowserApi.getTabFromCurrentWindow();
|
2018-04-14 06:02:55 +02:00
|
|
|
if (tab != null) {
|
2018-04-06 20:03:35 +02:00
|
|
|
this.url = tab.url;
|
2021-04-23 10:45:20 +02:00
|
|
|
} else {
|
2018-04-14 06:02:55 +02:00
|
|
|
this.loginCiphers = [];
|
2018-04-06 20:03:35 +02:00
|
|
|
this.loaded = true;
|
2021-12-21 15:43:35 +01:00
|
|
|
return;
|
2021-04-23 10:45:20 +02:00
|
|
|
}
|
|
|
|
|
2018-04-23 19:04:11 +02:00
|
|
|
this.hostname = Utils.getHostname(this.url);
|
2018-09-27 16:52:01 +02:00
|
|
|
this.pageDetails = [];
|
2018-04-06 20:03:35 +02:00
|
|
|
BrowserApi.tabSendMessage(tab, {
|
|
|
|
command: "collectPageDetails",
|
|
|
|
tab: tab,
|
2018-04-06 21:33:20 +02:00
|
|
|
sender: BroadcasterSubscriptionId,
|
2018-04-06 20:03:35 +02:00
|
|
|
});
|
2021-12-21 15:43:35 +01:00
|
|
|
|
2018-11-21 20:31:34 +01:00
|
|
|
const otherTypes: CipherType[] = [];
|
2022-01-27 22:22:51 +01:00
|
|
|
const dontShowCards = await this.stateService.getDontShowCardsCurrentTab();
|
|
|
|
const dontShowIdentities = await this.stateService.getDontShowIdentitiesCurrentTab();
|
2022-05-09 14:19:18 +02:00
|
|
|
this.showOrganizations = await this.organizationService.hasOrganizations();
|
2018-04-06 20:03:35 +02:00
|
|
|
if (!dontShowCards) {
|
|
|
|
otherTypes.push(CipherType.Card);
|
|
|
|
}
|
2018-11-21 20:31:34 +01:00
|
|
|
if (!dontShowIdentities) {
|
|
|
|
otherTypes.push(CipherType.Identity);
|
2021-12-21 15:43:35 +01:00
|
|
|
}
|
|
|
|
|
2018-11-21 20:31:34 +01:00
|
|
|
const ciphers = await this.cipherService.getAllDecryptedForUrl(
|
2021-12-21 15:43:35 +01:00
|
|
|
this.url,
|
2018-11-21 20:31:34 +01:00
|
|
|
otherTypes.length > 0 ? otherTypes : null
|
2021-12-21 15:43:35 +01:00
|
|
|
);
|
|
|
|
|
2018-04-06 20:18:28 +02:00
|
|
|
this.loginCiphers = [];
|
|
|
|
this.cardCiphers = [];
|
2018-04-06 20:03:35 +02:00
|
|
|
this.identityCiphers = [];
|
2021-12-21 15:43:35 +01:00
|
|
|
|
2021-03-02 19:31:52 +01:00
|
|
|
ciphers.forEach((c) => {
|
2022-05-09 14:19:18 +02:00
|
|
|
if (!this.vaultFilterService.filterCipherForSelectedVault(c)) {
|
|
|
|
switch (c.type) {
|
|
|
|
case CipherType.Login:
|
|
|
|
this.loginCiphers.push(c);
|
|
|
|
break;
|
|
|
|
case CipherType.Card:
|
|
|
|
this.cardCiphers.push(c);
|
|
|
|
break;
|
|
|
|
case CipherType.Identity:
|
|
|
|
this.identityCiphers.push(c);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2021-12-21 15:43:35 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-04-14 03:23:11 +02:00
|
|
|
this.loginCiphers = this.loginCiphers.sort((a, b) =>
|
|
|
|
this.cipherService.sortCiphersByLastUsedThenName(a, b)
|
2021-12-21 15:43:35 +01:00
|
|
|
);
|
2018-04-06 20:03:35 +02:00
|
|
|
this.loaded = true;
|
2021-12-21 15:43:35 +01:00
|
|
|
}
|
2018-04-05 04:59:42 +02:00
|
|
|
}
|