mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 00:33:44 +00:00
[PM-4414] Bugfix - On page URL change, display notifications that have not been dismissed nor expired (#6637)
* on page location change, display notifications that have not been dismissed nor expired * also dismiss notifications when removing them from the queue during cleanup * cleanup
This commit is contained in:
@@ -23,6 +23,7 @@ import { NotificationQueueMessageType } from "../../background/models/notificati
|
|||||||
import { BrowserApi } from "../../platform/browser/browser-api";
|
import { BrowserApi } from "../../platform/browser/browser-api";
|
||||||
import { BrowserStateService } from "../../platform/services/abstractions/browser-state.service";
|
import { BrowserStateService } from "../../platform/services/abstractions/browser-state.service";
|
||||||
import { openAddEditVaultItemPopout } from "../../vault/popup/utils/vault-popout-window";
|
import { openAddEditVaultItemPopout } from "../../vault/popup/utils/vault-popout-window";
|
||||||
|
import { NOTIFICATION_BAR_LIFESPAN_MS } from "../constants";
|
||||||
import { AutofillService } from "../services/abstractions/autofill.service";
|
import { AutofillService } from "../services/abstractions/autofill.service";
|
||||||
|
|
||||||
export default class NotificationBackground {
|
export default class NotificationBackground {
|
||||||
@@ -123,6 +124,9 @@ export default class NotificationBackground {
|
|||||||
case "bgUnlockPopoutOpened":
|
case "bgUnlockPopoutOpened":
|
||||||
await this.unlockVault(sender.tab);
|
await this.unlockVault(sender.tab);
|
||||||
break;
|
break;
|
||||||
|
case "checkNotificationQueue":
|
||||||
|
await this.checkNotificationQueue(sender.tab);
|
||||||
|
break;
|
||||||
case "bgReopenUnlockPopout":
|
case "bgReopenUnlockPopout":
|
||||||
await openUnlockPopout(sender.tab);
|
await openUnlockPopout(sender.tab);
|
||||||
break;
|
break;
|
||||||
@@ -150,10 +154,11 @@ export default class NotificationBackground {
|
|||||||
private cleanupNotificationQueue() {
|
private cleanupNotificationQueue() {
|
||||||
for (let i = this.notificationQueue.length - 1; i >= 0; i--) {
|
for (let i = this.notificationQueue.length - 1; i >= 0; i--) {
|
||||||
if (this.notificationQueue[i].expires < new Date()) {
|
if (this.notificationQueue[i].expires < new Date()) {
|
||||||
|
BrowserApi.tabSendMessageData(this.notificationQueue[i].tab, "closeNotificationBar");
|
||||||
this.notificationQueue.splice(i, 1);
|
this.notificationQueue.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setTimeout(() => this.cleanupNotificationQueue(), 2 * 60 * 1000); // check every 2 minutes
|
setTimeout(() => this.cleanupNotificationQueue(), 30000); // check every 30 seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
private async doNotificationQueueCheck(tab: chrome.tabs.Tab): Promise<void> {
|
private async doNotificationQueueCheck(tab: chrome.tabs.Tab): Promise<void> {
|
||||||
@@ -168,7 +173,7 @@ export default class NotificationBackground {
|
|||||||
|
|
||||||
for (let i = 0; i < this.notificationQueue.length; i++) {
|
for (let i = 0; i < this.notificationQueue.length; i++) {
|
||||||
if (
|
if (
|
||||||
this.notificationQueue[i].tabId !== tab.id ||
|
this.notificationQueue[i].tab.id !== tab.id ||
|
||||||
this.notificationQueue[i].domain !== tabDomain
|
this.notificationQueue[i].domain !== tabDomain
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
@@ -220,7 +225,7 @@ export default class NotificationBackground {
|
|||||||
|
|
||||||
private removeTabFromNotificationQueue(tab: chrome.tabs.Tab) {
|
private removeTabFromNotificationQueue(tab: chrome.tabs.Tab) {
|
||||||
for (let i = this.notificationQueue.length - 1; i >= 0; i--) {
|
for (let i = this.notificationQueue.length - 1; i >= 0; i--) {
|
||||||
if (this.notificationQueue[i].tabId === tab.id) {
|
if (this.notificationQueue[i].tab.id === tab.id) {
|
||||||
this.notificationQueue.splice(i, 1);
|
this.notificationQueue.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,8 +294,8 @@ export default class NotificationBackground {
|
|||||||
password: loginInfo.password,
|
password: loginInfo.password,
|
||||||
domain: loginDomain,
|
domain: loginDomain,
|
||||||
uri: loginInfo.url,
|
uri: loginInfo.url,
|
||||||
tabId: tab.id,
|
tab: tab,
|
||||||
expires: new Date(new Date().getTime() + 5 * 60000), // 5 minutes
|
expires: new Date(new Date().getTime() + NOTIFICATION_BAR_LIFESPAN_MS),
|
||||||
wasVaultLocked: isVaultLocked,
|
wasVaultLocked: isVaultLocked,
|
||||||
};
|
};
|
||||||
this.notificationQueue.push(message);
|
this.notificationQueue.push(message);
|
||||||
@@ -353,8 +358,8 @@ export default class NotificationBackground {
|
|||||||
cipherId: cipherId,
|
cipherId: cipherId,
|
||||||
newPassword: newPassword,
|
newPassword: newPassword,
|
||||||
domain: loginDomain,
|
domain: loginDomain,
|
||||||
tabId: tab.id,
|
tab: tab,
|
||||||
expires: new Date(new Date().getTime() + 5 * 60000), // 5 minutes
|
expires: new Date(new Date().getTime() + NOTIFICATION_BAR_LIFESPAN_MS),
|
||||||
wasVaultLocked: isVaultLocked,
|
wasVaultLocked: isVaultLocked,
|
||||||
};
|
};
|
||||||
this.notificationQueue.push(message);
|
this.notificationQueue.push(message);
|
||||||
@@ -366,7 +371,7 @@ export default class NotificationBackground {
|
|||||||
const message: AddUnlockVaultQueueMessage = {
|
const message: AddUnlockVaultQueueMessage = {
|
||||||
type: NotificationQueueMessageType.UnlockVault,
|
type: NotificationQueueMessageType.UnlockVault,
|
||||||
domain: loginDomain,
|
domain: loginDomain,
|
||||||
tabId: tab.id,
|
tab: tab,
|
||||||
expires: new Date(new Date().getTime() + 0.5 * 60000), // 30 seconds
|
expires: new Date(new Date().getTime() + 0.5 * 60000), // 30 seconds
|
||||||
wasVaultLocked: true,
|
wasVaultLocked: true,
|
||||||
};
|
};
|
||||||
@@ -378,7 +383,7 @@ export default class NotificationBackground {
|
|||||||
private async saveOrUpdateCredentials(tab: chrome.tabs.Tab, edit: boolean, folderId?: string) {
|
private async saveOrUpdateCredentials(tab: chrome.tabs.Tab, edit: boolean, folderId?: string) {
|
||||||
for (let i = this.notificationQueue.length - 1; i >= 0; i--) {
|
for (let i = this.notificationQueue.length - 1; i >= 0; i--) {
|
||||||
const queueMessage = this.notificationQueue[i];
|
const queueMessage = this.notificationQueue[i];
|
||||||
if (queueMessage.tabId !== tab.id || !(queueMessage.type in NotificationQueueMessageType)) {
|
if (queueMessage.tab.id !== tab.id || !(queueMessage.type in NotificationQueueMessageType)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,7 +481,7 @@ export default class NotificationBackground {
|
|||||||
for (let i = this.notificationQueue.length - 1; i >= 0; i--) {
|
for (let i = this.notificationQueue.length - 1; i >= 0; i--) {
|
||||||
const queueMessage = this.notificationQueue[i];
|
const queueMessage = this.notificationQueue[i];
|
||||||
if (
|
if (
|
||||||
queueMessage.tabId !== tab.id ||
|
queueMessage.tab.id !== tab.id ||
|
||||||
queueMessage.type !== NotificationQueueMessageType.AddLogin
|
queueMessage.type !== NotificationQueueMessageType.AddLogin
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -27,3 +27,5 @@ export const GENERATE_PASSWORD_ID = "generate-password";
|
|||||||
export const NOOP_COMMAND_SUFFIX = "noop";
|
export const NOOP_COMMAND_SUFFIX = "noop";
|
||||||
export const ROOT_ID = "root";
|
export const ROOT_ID = "root";
|
||||||
export const SEPARATOR_ID = "separator";
|
export const SEPARATOR_ID = "separator";
|
||||||
|
|
||||||
|
export const NOTIFICATION_BAR_LIFESPAN_MS = 150000; // 150 seconds
|
||||||
|
|||||||
@@ -325,6 +325,10 @@ async function loadNotificationBar() {
|
|||||||
// On first load or page change, start observing the DOM as early as possible
|
// On first load or page change, start observing the DOM as early as possible
|
||||||
// to avoid missing any forms that are added after the page loads
|
// to avoid missing any forms that are added after the page loads
|
||||||
observeDom();
|
observeDom();
|
||||||
|
|
||||||
|
sendPlatformMessage({
|
||||||
|
command: "checkNotificationQueue",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a safeguard in case the observer misses a SPA page change.
|
// This is a safeguard in case the observer misses a SPA page change.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { NotificationQueueMessageType } from "./notificationQueueMessageType";
|
|||||||
export default class NotificationQueueMessage {
|
export default class NotificationQueueMessage {
|
||||||
type: NotificationQueueMessageType;
|
type: NotificationQueueMessageType;
|
||||||
domain: string;
|
domain: string;
|
||||||
tabId: number;
|
tab: chrome.tabs.Tab;
|
||||||
expires: Date;
|
expires: Date;
|
||||||
wasVaultLocked: boolean;
|
wasVaultLocked: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user