[PM-5551] Removing Autofill v2 and AutofillOverlay Feature Flags (#7642)

* [PM-5551] Removing Autofillv2 and AutofillOverlay Feature Flags

* [PM-5551] Fully removing references to autofill v1
This commit is contained in:
Cesar Gonzalez 2024-01-22 11:11:07 -06:00 committed by GitHub
parent ec7c3878c9
commit 0127db44a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 46 additions and 1386 deletions

View File

@ -12,7 +12,6 @@ storybook-static
apps/browser/config/config.js
apps/browser/src/auth/scripts/duo.js
apps/browser/src/autofill/content/autofill.js
apps/desktop/desktop_native
apps/desktop/src/auth/scripts/duo.js

View File

@ -9,7 +9,6 @@ storybook-static
# External libraries / auto synced locales
apps/browser/src/_locales
apps/browser/src/auth/scripts/duo.js
apps/browser/src/autofill/content/autofill.js
apps/browser/src/safari
apps/desktop/src/locales

File diff suppressed because it is too large Load Diff

View File

@ -363,9 +363,9 @@ async function loadNotificationBar() {
* `main.background.ts : collectPageDetailsForContentScript`
*
* (3) `main.background.ts : collectPageDetailsForContentScript`
* sends a message with command `collectPageDetails` to the `autofill.js` content script
* sends a message with command `collectPageDetails` to the `autofill-init.js` content script
*
* (4) `autofill.js` content script runs a `collect(document)` method.
* (4) `autofill-init.js` content script runs a `collect(document)` method.
* The result is sent via message with command `collectPageDetailsResponse` to `notification.background.ts : processMessage(...)`
*
* (5) `notification.background.ts : processMessage(...)` gathers forms with password fields and passes them and the page details
@ -410,7 +410,7 @@ async function loadNotificationBar() {
// If the form could not be retrieved by its HTML ID, retrieve it by its index pulled from the opid
if (formEl == null) {
// opid stands for OnePassword ID - uniquely ID's an element on a page
// and is generated in `autofill.js`
// and is generated in `autofill-init.js`
// Each form has an opid and each element has an opid and its parent form opid
const index = parseInt(f.form.opid.split("__")[2], null);
formEl = document.getElementsByTagName("form")[index];
@ -972,8 +972,8 @@ async function loadNotificationBar() {
* @param {HTMLElement} el
* @returns {boolean} Returns `true` if the element is visible and `false` otherwise
*
* Copied from autofill.js and converted to TypeScript;
* TODO: could be refactored to be in a shared location if autofill.js is converted to TS
* Copied from autofill-init.js and converted to TypeScript;
* TODO: could be refactored to be in a shared location if autofill-init.js is converted to TS
*/
function isElementVisible(el: HTMLElement): boolean {
let theEl: Node | null = el;

View File

@ -26,39 +26,37 @@
{{ autofillKeyboardHelperText }}
</div>
</div>
<ng-container *ngIf="isAutoFillOverlayFlagEnabled">
<div class="box">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="autofill-overlay-settings">{{ "showAutoFillMenuOnFormFields" | i18n }}</label>
<select
id="autofill-overlay-settings"
name="autofill-overlay-settings"
[(ngModel)]="autoFillOverlayVisibility"
(change)="updateAutoFillOverlayVisibility()"
>
<option *ngFor="let o of autoFillOverlayVisibilityOptions" [ngValue]="o.value">
{{ o.name }}
</option>
</select>
</div>
<div class="box-footer" *ngIf="accountSwitcherEnabled">
{{ "showAutoFillMenuOnFormFieldsDescAlt" | i18n }}
</div>
<div class="box-footer">
{{ "turnOffBrowserBuiltInPasswordManagerSettings" | i18n }}
<a
[attr.href]="disablePasswordManagerLink"
(click)="openDisablePasswordManagerLink($event)"
target="_blank"
rel="noopener noreferrer"
>
{{ "turnOffBrowserBuiltInPasswordManagerSettingsLink" | i18n }}
</a>
</div>
<div class="box">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="autofill-overlay-settings">{{ "showAutoFillMenuOnFormFields" | i18n }}</label>
<select
id="autofill-overlay-settings"
name="autofill-overlay-settings"
[(ngModel)]="autoFillOverlayVisibility"
(change)="updateAutoFillOverlayVisibility()"
>
<option *ngFor="let o of autoFillOverlayVisibilityOptions" [ngValue]="o.value">
{{ o.name }}
</option>
</select>
</div>
<div class="box-footer" *ngIf="accountSwitcherEnabled">
{{ "showAutoFillMenuOnFormFieldsDescAlt" | i18n }}
</div>
<div class="box-footer">
{{ "turnOffBrowserBuiltInPasswordManagerSettings" | i18n }}
<a
[attr.href]="disablePasswordManagerLink"
(click)="openDisablePasswordManagerLink($event)"
target="_blank"
rel="noopener noreferrer"
>
{{ "turnOffBrowserBuiltInPasswordManagerSettingsLink" | i18n }}
</a>
</div>
</div>
</ng-container>
</div>
<div class="box tw-mt-4">
<div class="box-content">
<div class="box-content-row box-content-row-checkbox" appBoxRow>

View File

@ -1,7 +1,6 @@
import { Component, OnInit } from "@angular/core";
import { SettingsService } from "@bitwarden/common/abstractions/settings.service";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@ -18,7 +17,6 @@ import { AutofillOverlayVisibility } from "../../utils/autofill-overlay.enum";
templateUrl: "autofill.component.html",
})
export class AutofillComponent implements OnInit {
protected isAutoFillOverlayFlagEnabled = false;
protected autoFillOverlayVisibility: number;
protected autoFillOverlayVisibilityOptions: any[];
protected disablePasswordManagerLink: string;
@ -70,9 +68,6 @@ export class AutofillComponent implements OnInit {
}
async ngOnInit() {
this.isAutoFillOverlayFlagEnabled = await this.configService.getFeatureFlag<boolean>(
FeatureFlag.AutofillOverlay,
);
this.autoFillOverlayVisibility =
(await this.settingsService.getAutoFillOverlayVisibility()) || AutofillOverlayVisibility.Off;

View File

@ -2,7 +2,6 @@ import { mock, mockReset } from "jest-mock-extended";
import { UserVerificationService } from "@bitwarden/common/auth/services/user-verification/user-verification.service";
import { EventType } from "@bitwarden/common/enums";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { ConfigService } from "@bitwarden/common/platform/services/config/config.service";
import { EventCollectionService } from "@bitwarden/common/services/event/event-collection.service";
@ -144,8 +143,7 @@ describe("AutofillService", () => {
});
describe("injectAutofillScripts", () => {
const autofillV1Script = "autofill.js";
const autofillV2BootstrapScript = "bootstrap-autofill.js";
const autofillBootstrapScript = "bootstrap-autofill.js";
const autofillOverlayBootstrapScript = "bootstrap-autofill-overlay.js";
const defaultAutofillScripts = ["autofiller.js", "notificationBar.js", "contextMenuHandler.js"];
const defaultExecuteScriptOptions = { runAt: "document_start" };
@ -161,45 +159,16 @@ describe("AutofillService", () => {
it("accepts an extension message sender and injects the autofill scripts into the tab of the sender", async () => {
await autofillService.injectAutofillScripts(sender.tab, sender.frameId, true);
[autofillV1Script, ...defaultAutofillScripts].forEach((scriptName) => {
[autofillOverlayBootstrapScript, ...defaultAutofillScripts].forEach((scriptName) => {
expect(BrowserApi.executeScriptInTab).toHaveBeenCalledWith(tabMock.id, {
file: `content/${scriptName}`,
frameId: sender.frameId,
...defaultExecuteScriptOptions,
});
});
expect(BrowserApi.executeScriptInTab).not.toHaveBeenCalledWith(tabMock.id, {
file: `content/${autofillV2BootstrapScript}`,
frameId: sender.frameId,
...defaultExecuteScriptOptions,
});
});
it("will inject the bootstrap-autofill script if the enableAutofillV2 flag is set", async () => {
jest
.spyOn(configService, "getFeatureFlag")
.mockImplementation((flag) => Promise.resolve(flag === FeatureFlag.AutofillV2));
await autofillService.injectAutofillScripts(sender.tab, sender.frameId);
expect(BrowserApi.executeScriptInTab).toHaveBeenCalledWith(tabMock.id, {
file: `content/${autofillV2BootstrapScript}`,
frameId: sender.frameId,
...defaultExecuteScriptOptions,
});
expect(BrowserApi.executeScriptInTab).not.toHaveBeenCalledWith(tabMock.id, {
file: `content/${autofillV1Script}`,
frameId: sender.frameId,
...defaultExecuteScriptOptions,
});
});
it("will inject the bootstrap-autofill-overlay script if the enableAutofillOverlay flag is set and the user has the autofill overlay enabled", async () => {
jest
.spyOn(configService, "getFeatureFlag")
.mockImplementation((flag) =>
Promise.resolve(flag === FeatureFlag.AutofillOverlay || flag === FeatureFlag.AutofillV2),
);
it("will inject the bootstrap-autofill-overlay script if the user has the autofill overlay enabled", async () => {
jest
.spyOn(autofillService["settingsService"], "getAutoFillOverlayVisibility")
.mockResolvedValue(AutofillOverlayVisibility.OnFieldFocus);
@ -212,23 +181,13 @@ describe("AutofillService", () => {
...defaultExecuteScriptOptions,
});
expect(BrowserApi.executeScriptInTab).not.toHaveBeenCalledWith(tabMock.id, {
file: `content/${autofillV1Script}`,
frameId: sender.frameId,
...defaultExecuteScriptOptions,
});
expect(BrowserApi.executeScriptInTab).not.toHaveBeenCalledWith(tabMock.id, {
file: `content/${autofillV2BootstrapScript}`,
file: `content/${autofillBootstrapScript}`,
frameId: sender.frameId,
...defaultExecuteScriptOptions,
});
});
it("will inject the bootstrap-autofill script if the enableAutofillOverlay flag is set but the user does not have the autofill overlay enabled", async () => {
jest
.spyOn(configService, "getFeatureFlag")
.mockImplementation((flag) =>
Promise.resolve(flag === FeatureFlag.AutofillOverlay || flag === FeatureFlag.AutofillV2),
);
it("will inject the bootstrap-autofill script if the user does not have the autofill overlay enabled", async () => {
jest
.spyOn(autofillService["settingsService"], "getAutoFillOverlayVisibility")
.mockResolvedValue(AutofillOverlayVisibility.Off);
@ -236,12 +195,12 @@ describe("AutofillService", () => {
await autofillService.injectAutofillScripts(sender.tab, sender.frameId);
expect(BrowserApi.executeScriptInTab).toHaveBeenCalledWith(tabMock.id, {
file: `content/${autofillV2BootstrapScript}`,
file: `content/${autofillBootstrapScript}`,
frameId: sender.frameId,
...defaultExecuteScriptOptions,
});
expect(BrowserApi.executeScriptInTab).not.toHaveBeenCalledWith(tabMock.id, {
file: `content/${autofillV1Script}`,
file: `content/${autofillOverlayBootstrapScript}`,
frameId: sender.frameId,
...defaultExecuteScriptOptions,
});

View File

@ -2,7 +2,6 @@ import { EventCollectionService } from "@bitwarden/common/abstractions/event/eve
import { SettingsService } from "@bitwarden/common/abstractions/settings.service";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { EventType } from "@bitwarden/common/enums";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
@ -92,21 +91,11 @@ export default class AutofillService implements AutofillServiceInterface {
frameId = 0,
triggeringOnPageLoad = true,
): Promise<void> {
const autofillV2 = await this.configService.getFeatureFlag<boolean>(FeatureFlag.AutofillV2);
const autofillOverlay = await this.configService.getFeatureFlag<boolean>(
FeatureFlag.AutofillOverlay,
);
let mainAutofillScript = "autofill.js";
const isUsingAutofillOverlay =
autofillOverlay &&
(await this.settingsService.getAutoFillOverlayVisibility()) !== AutofillOverlayVisibility.Off;
if (autofillV2) {
mainAutofillScript = isUsingAutofillOverlay
? "bootstrap-autofill-overlay.js"
: "bootstrap-autofill.js";
}
const mainAutofillScript = isUsingAutofillOverlay
? "bootstrap-autofill-overlay.js"
: "bootstrap-autofill.js";
const injectedScripts = [mainAutofillScript];
@ -142,7 +131,7 @@ export default class AutofillService implements AutofillServiceInterface {
const passwordFields = AutofillService.loadPasswordFields(pageDetails, true, true, false, true);
// TODO: this logic prevents multi-step account creation forms (that just start with email)
// from being passed on to the notification bar content script - even if autofill.js found the form and email field.
// from being passed on to the notification bar content script - even if autofill-init.js found the form and email field.
// ex: https://signup.live.com/
if (passwordFields.length === 0) {
return formData;

View File

@ -18,12 +18,7 @@
"content_scripts": [
{
"all_frames": true,
"js": [
"content/autofill.js",
"content/autofiller.js",
"content/notificationBar.js",
"content/contextMenuHandler.js"
],
"js": ["content/trigger-autofill-script-injection.js"],
"matches": ["http://*/*", "https://*/*", "file:///*"],
"run_at": "document_start"
},

View File

@ -164,7 +164,6 @@ const mainConfig = {
"popup/main": "./src/popup/main.ts",
"content/trigger-autofill-script-injection":
"./src/autofill/content/trigger-autofill-script-injection.ts",
"content/autofill": "./src/autofill/content/autofill.js",
"content/bootstrap-autofill": "./src/autofill/content/bootstrap-autofill.ts",
"content/bootstrap-autofill-overlay": "./src/autofill/content/bootstrap-autofill-overlay.ts",
"content/autofiller": "./src/autofill/content/autofiller.ts",

View File

@ -1,7 +1,5 @@
export enum FeatureFlag {
PasswordlessLogin = "passwordless-login",
AutofillV2 = "autofill-v2",
AutofillOverlay = "autofill-overlay",
BrowserFilelessImport = "browser-fileless-import",
ItemShare = "item-share",
FlexibleCollectionsV1 = "flexible-collections-v-1", // v-1 is intentional