[PM-8833] Setting up password generator to refresh only when a form is blurred entirely
This commit is contained in:
parent
43ed792823
commit
55da615caa
|
@ -1,5 +1,4 @@
|
||||||
import {
|
import {
|
||||||
BehaviorSubject,
|
|
||||||
debounceTime,
|
debounceTime,
|
||||||
firstValueFrom,
|
firstValueFrom,
|
||||||
map,
|
map,
|
||||||
|
@ -89,9 +88,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
private readonly openUnlockPopout = openUnlockPopout;
|
private readonly openUnlockPopout = openUnlockPopout;
|
||||||
private readonly openViewVaultItemPopout = openViewVaultItemPopout;
|
private readonly openViewVaultItemPopout = openViewVaultItemPopout;
|
||||||
private readonly openAddEditVaultItemPopout = openAddEditVaultItemPopout;
|
private readonly openAddEditVaultItemPopout = openAddEditVaultItemPopout;
|
||||||
private readonly updateOverlayCiphersSubject = new BehaviorSubject<UpdateOverlayCiphersParams>(
|
private readonly updateOverlayCiphersSubject = new Subject<UpdateOverlayCiphersParams>();
|
||||||
null,
|
|
||||||
);
|
|
||||||
private readonly storeInlineMenuFido2CredentialsSubject = new ReplaySubject<number>(1);
|
private readonly storeInlineMenuFido2CredentialsSubject = new ReplaySubject<number>(1);
|
||||||
private readonly startInlineMenuDelayedCloseSubject: Subject<void> = new Subject<void>();
|
private readonly startInlineMenuDelayedCloseSubject: Subject<void> = new Subject<void>();
|
||||||
private readonly cancelInlineMenuDelayedCloseSubject: Subject<boolean> = new Subject<boolean>();
|
private readonly cancelInlineMenuDelayedCloseSubject: Subject<boolean> = new Subject<boolean>();
|
||||||
|
@ -123,7 +120,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
private isInlineMenuListVisible: boolean = false;
|
private isInlineMenuListVisible: boolean = false;
|
||||||
private showPasskeysLabelsWithinInlineMenu: boolean = false;
|
private showPasskeysLabelsWithinInlineMenu: boolean = false;
|
||||||
private iconsServerUrl: string;
|
private iconsServerUrl: string;
|
||||||
private mostRecentlyGeneratedPassword: string;
|
private generatedPassword: string;
|
||||||
private readonly extensionMessageHandlers: OverlayBackgroundExtensionMessageHandlers = {
|
private readonly extensionMessageHandlers: OverlayBackgroundExtensionMessageHandlers = {
|
||||||
autofillOverlayElementClosed: ({ message, sender }) =>
|
autofillOverlayElementClosed: ({ message, sender }) =>
|
||||||
this.overlayElementClosed(message, sender),
|
this.overlayElementClosed(message, sender),
|
||||||
|
@ -181,7 +178,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
redirectAutofillInlineMenuFocusOut: ({ message, port }) =>
|
redirectAutofillInlineMenuFocusOut: ({ message, port }) =>
|
||||||
this.redirectInlineMenuFocusOut(message, port),
|
this.redirectInlineMenuFocusOut(message, port),
|
||||||
updateAutofillInlineMenuListHeight: ({ message }) => this.updateInlineMenuListHeight(message),
|
updateAutofillInlineMenuListHeight: ({ message }) => this.updateInlineMenuListHeight(message),
|
||||||
refreshGeneratedPassword: () => this.refreshGeneratedPassword(),
|
refreshGeneratedPassword: () => this.updateGeneratedPassword(true),
|
||||||
fillGeneratedPassword: ({ port }) => this.fillGeneratedPassword(port),
|
fillGeneratedPassword: ({ port }) => this.fillGeneratedPassword(port),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -204,13 +201,11 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
this.initOverlayEventObservables();
|
this.initOverlayEventObservables();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async generatePassword(): Promise<string> {
|
private async generatePassword(): Promise<void> {
|
||||||
const options = (await this.passwordGenerationService.getOptions())?.[0] ?? {};
|
const options = (await this.passwordGenerationService.getOptions())?.[0] ?? {};
|
||||||
const password = await this.passwordGenerationService.generatePassword(options);
|
const password = await this.passwordGenerationService.generatePassword(options);
|
||||||
await this.passwordGenerationService.addHistory(password);
|
await this.passwordGenerationService.addHistory(password);
|
||||||
this.mostRecentlyGeneratedPassword = password;
|
this.generatedPassword = password;
|
||||||
|
|
||||||
return password;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -300,7 +295,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
delete this.portKeyForTab[tabId];
|
delete this.portKeyForTab[tabId];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mostRecentlyGeneratedPassword = null;
|
this.generatedPassword = null;
|
||||||
this.focusedFieldData = null;
|
this.focusedFieldData = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,6 +338,8 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
this.inlineMenuFido2Credentials.clear();
|
this.inlineMenuFido2Credentials.clear();
|
||||||
this.storeInlineMenuFido2CredentialsSubject.next(currentTab.id);
|
this.storeInlineMenuFido2CredentialsSubject.next(currentTab.id);
|
||||||
|
|
||||||
|
await this.generatePassword();
|
||||||
|
|
||||||
this.inlineMenuCiphers = new Map();
|
this.inlineMenuCiphers = new Map();
|
||||||
const ciphersViews = await this.getCipherViews(currentTab, updateAllCipherTypes);
|
const ciphersViews = await this.getCipherViews(currentTab, updateAllCipherTypes);
|
||||||
for (let cipherIndex = 0; cipherIndex < ciphersViews.length; cipherIndex++) {
|
for (let cipherIndex = 0; cipherIndex < ciphersViews.length; cipherIndex++) {
|
||||||
|
@ -1081,6 +1078,8 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
sender: chrome.runtime.MessageSender,
|
sender: chrome.runtime.MessageSender,
|
||||||
{ forceCloseInlineMenu, overlayElement }: CloseInlineMenuMessage = {},
|
{ forceCloseInlineMenu, overlayElement }: CloseInlineMenuMessage = {},
|
||||||
) {
|
) {
|
||||||
|
this.generatedPassword = null;
|
||||||
|
|
||||||
const command = "closeAutofillInlineMenu";
|
const command = "closeAutofillInlineMenu";
|
||||||
const sendOptions = { frameId: 0 };
|
const sendOptions = { frameId: 0 };
|
||||||
if (forceCloseInlineMenu) {
|
if (forceCloseInlineMenu) {
|
||||||
|
@ -1375,8 +1374,11 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
previousFocusedFieldData?.inlineMenuFillType === InlineMenuFillType.AccountCreationUsername &&
|
previousFocusedFieldData?.inlineMenuFillType === InlineMenuFillType.AccountCreationUsername &&
|
||||||
this.focusedFieldData.inlineMenuFillType !== InlineMenuFillType.AccountCreationUsername;
|
this.focusedFieldData.inlineMenuFillType !== InlineMenuFillType.AccountCreationUsername;
|
||||||
|
|
||||||
if (this.focusedFieldData.inlineMenuFillType === InlineMenuFillType.PasswordGeneration) {
|
if (
|
||||||
this.refreshGeneratedPassword().catch((error) => this.logService.error(error));
|
this.isInlineMenuButtonVisible &&
|
||||||
|
this.focusedFieldData.inlineMenuFillType === InlineMenuFillType.PasswordGeneration
|
||||||
|
) {
|
||||||
|
this.updateGeneratedPassword().catch((error) => this.logService.error(error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1413,7 +1415,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
this.focusedFieldData.inlineMenuFillType === CipherType.Login &&
|
this.focusedFieldData.inlineMenuFillType === CipherType.Login &&
|
||||||
this.focusedFieldData.accountCreationFieldType === "password"
|
this.focusedFieldData.accountCreationFieldType === "password"
|
||||||
) {
|
) {
|
||||||
await this.refreshGeneratedPassword();
|
await this.updateGeneratedPassword();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1425,16 +1427,20 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async refreshGeneratedPassword() {
|
private async updateGeneratedPassword(refreshPassword: boolean = false) {
|
||||||
|
if (!this.generatedPassword || refreshPassword) {
|
||||||
|
await this.generatePassword();
|
||||||
|
}
|
||||||
|
|
||||||
this.inlineMenuListPort?.postMessage({
|
this.inlineMenuListPort?.postMessage({
|
||||||
command: "updateAutofillInlineMenuGeneratedPassword",
|
command: "updateAutofillInlineMenuGeneratedPassword",
|
||||||
generatedPassword: await this.generatePassword(),
|
generatedPassword: this.generatedPassword,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Most of the logic here likely should exist within the autofill service instead of here.
|
// TODO: Most of the logic here likely should exist within the autofill service instead of here.
|
||||||
private async fillGeneratedPassword(port: chrome.runtime.Port) {
|
private async fillGeneratedPassword(port: chrome.runtime.Port) {
|
||||||
if (!this.mostRecentlyGeneratedPassword) {
|
if (!this.generatedPassword) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1472,7 +1478,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
|
|
||||||
const cipher = this.buildLoginCipherView({
|
const cipher = this.buildLoginCipherView({
|
||||||
username: "",
|
username: "",
|
||||||
password: this.mostRecentlyGeneratedPassword,
|
password: this.generatedPassword,
|
||||||
hostname: "",
|
hostname: "",
|
||||||
uri: "",
|
uri: "",
|
||||||
});
|
});
|
||||||
|
@ -2401,18 +2407,13 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
this.portKeyForTab[port.sender.tab.id] = generateRandomChars(12);
|
this.portKeyForTab[port.sender.tab.id] = generateRandomChars(12);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Pull this into a separate method
|
|
||||||
const authStatus = await this.getAuthStatus();
|
|
||||||
const showInlineMenuAccountCreation = this.showInlineMenuAccountCreation();
|
const showInlineMenuAccountCreation = this.showInlineMenuAccountCreation();
|
||||||
let generatedPassword = null;
|
const showInlineMenuPasswordGenerator = this.showInlineMenuPasswordGenerator(
|
||||||
if (
|
isInlineMenuListPort,
|
||||||
authStatus === AuthenticationStatus.Unlocked &&
|
showInlineMenuAccountCreation,
|
||||||
isInlineMenuListPort &&
|
);
|
||||||
(this.focusedFieldData?.inlineMenuFillType === InlineMenuFillType.PasswordGeneration ||
|
if (showInlineMenuPasswordGenerator && !this.generatedPassword) {
|
||||||
(showInlineMenuAccountCreation &&
|
await this.generatePassword();
|
||||||
this.focusedFieldData?.accountCreationFieldType === "password"))
|
|
||||||
) {
|
|
||||||
generatedPassword = await this.generatePassword();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.storeOverlayPort(port);
|
this.storeOverlayPort(port);
|
||||||
|
@ -2426,7 +2427,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
pageTitle: chrome.i18n.getMessage(
|
pageTitle: chrome.i18n.getMessage(
|
||||||
isInlineMenuListPort ? "bitwardenVault" : "bitwardenOverlayButton",
|
isInlineMenuListPort ? "bitwardenVault" : "bitwardenOverlayButton",
|
||||||
),
|
),
|
||||||
authStatus,
|
authStatus: await this.getAuthStatus(),
|
||||||
styleSheetUrl: chrome.runtime.getURL(
|
styleSheetUrl: chrome.runtime.getURL(
|
||||||
`overlay/menu-${isInlineMenuListPort ? "list" : "button"}.css`,
|
`overlay/menu-${isInlineMenuListPort ? "list" : "button"}.css`,
|
||||||
),
|
),
|
||||||
|
@ -2440,7 +2441,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
inlineMenuFillType: this.focusedFieldData?.inlineMenuFillType,
|
inlineMenuFillType: this.focusedFieldData?.inlineMenuFillType,
|
||||||
showInlineMenuAccountCreation,
|
showInlineMenuAccountCreation,
|
||||||
showPasskeysLabels: this.showPasskeysLabelsWithinInlineMenu,
|
showPasskeysLabels: this.showPasskeysLabelsWithinInlineMenu,
|
||||||
generatedPassword,
|
generatedPassword: showInlineMenuPasswordGenerator ? this.generatedPassword : null,
|
||||||
});
|
});
|
||||||
this.updateInlineMenuPosition(
|
this.updateInlineMenuPosition(
|
||||||
{
|
{
|
||||||
|
@ -2483,6 +2484,18 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private showInlineMenuPasswordGenerator(
|
||||||
|
isInlineMenuListPort: boolean,
|
||||||
|
showInlineMenuAccountCreation: boolean,
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
isInlineMenuListPort &&
|
||||||
|
(this.focusedFieldData?.inlineMenuFillType === InlineMenuFillType.PasswordGeneration ||
|
||||||
|
(showInlineMenuAccountCreation &&
|
||||||
|
this.focusedFieldData?.accountCreationFieldType === "password"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles messages sent to the overlay list or button ports.
|
* Handles messages sent to the overlay list or button ports.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue