mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-24 12:06:15 +01:00
[deps] Autofill: Update prettier to v3 (#7014)
* [deps] Autofill: Update prettier to v3 * prettier formatting updates --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jonathan Prusik <jprusik@classynemesis.com>
This commit is contained in:
parent
4ff5f38e89
commit
28de9439be
@ -48,7 +48,7 @@ const decorator = componentWrapperDecorator(
|
||||
},
|
||||
({ globals }) => {
|
||||
return { theme: `${globals["theme"]}` };
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const preview: Preview = {
|
||||
|
@ -171,7 +171,7 @@ function distSafariApp(cb, subBuildPath) {
|
||||
},
|
||||
() => {
|
||||
return cb;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ function safariCopyAssets(source, dest) {
|
||||
.on("error", reject)
|
||||
.pipe(gulpif("safari/Info.plist", replace("0.0.1", manifest.version)))
|
||||
.pipe(
|
||||
gulpif("safari/Info.plist", replace("0.0.2", process.env.BUILD_NUMBER || manifest.version))
|
||||
gulpif("safari/Info.plist", replace("0.0.2", process.env.BUILD_NUMBER || manifest.version)),
|
||||
)
|
||||
.pipe(gulpif("desktop.xcodeproj/project.pbxproj", replace("../../../build", "../safari/app")))
|
||||
.pipe(gulp.dest(dest))
|
||||
@ -208,8 +208,8 @@ async function safariCopyBuild(source, dest) {
|
||||
delete manifest.optional_permissions;
|
||||
manifest.permissions.push("nativeMessaging");
|
||||
return manifest;
|
||||
})
|
||||
)
|
||||
}),
|
||||
),
|
||||
)
|
||||
.pipe(gulp.dest(dest))
|
||||
.on("end", resolve);
|
||||
|
@ -18,12 +18,12 @@ export type OrganizationServiceInitOptions = OrganizationServiceFactoryOptions &
|
||||
|
||||
export function organizationServiceFactory(
|
||||
cache: { organizationService?: AbstractOrganizationService } & CachedServices,
|
||||
opts: OrganizationServiceInitOptions
|
||||
opts: OrganizationServiceInitOptions,
|
||||
): Promise<AbstractOrganizationService> {
|
||||
return factory(
|
||||
cache,
|
||||
"organizationService",
|
||||
opts,
|
||||
async () => new BrowserOrganizationService(await stateServiceFactory(cache, opts))
|
||||
async () => new BrowserOrganizationService(await stateServiceFactory(cache, opts)),
|
||||
);
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ export type PolicyServiceInitOptions = PolicyServiceFactoryOptions &
|
||||
|
||||
export function policyServiceFactory(
|
||||
cache: { policyService?: AbstractPolicyService } & CachedServices,
|
||||
opts: PolicyServiceInitOptions
|
||||
opts: PolicyServiceInitOptions,
|
||||
): Promise<AbstractPolicyService> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -33,7 +33,7 @@ export function policyServiceFactory(
|
||||
async () =>
|
||||
new BrowserPolicyService(
|
||||
await stateServiceFactory(cache, opts),
|
||||
await organizationServiceFactory(cache, opts)
|
||||
)
|
||||
await organizationServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ export class BrowserPolicyService extends PolicyService {
|
||||
if (activated === undefined) {
|
||||
this.stateService.setActivateAutoFillOnPageLoadFromPolicy(!autofillEnabled);
|
||||
}
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ export type AccountServiceInitOptions = AccountServiceFactoryOptions &
|
||||
|
||||
export function accountServiceFactory(
|
||||
cache: { accountService?: AccountService } & CachedServices,
|
||||
opts: AccountServiceInitOptions
|
||||
opts: AccountServiceInitOptions,
|
||||
): Promise<AccountService> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -38,7 +38,7 @@ export function accountServiceFactory(
|
||||
new AccountServiceImplementation(
|
||||
await messagingServiceFactory(cache, opts),
|
||||
await logServiceFactory(cache, opts),
|
||||
await globalStateProviderFactory(cache, opts)
|
||||
)
|
||||
await globalStateProviderFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -18,12 +18,12 @@ export type AuthRequestCryptoServiceInitOptions = AuthRequestCryptoServiceFactor
|
||||
|
||||
export function authRequestCryptoServiceFactory(
|
||||
cache: { authRequestCryptoService?: AuthRequestCryptoServiceAbstraction } & CachedServices,
|
||||
opts: AuthRequestCryptoServiceInitOptions
|
||||
opts: AuthRequestCryptoServiceInitOptions,
|
||||
): Promise<AuthRequestCryptoServiceAbstraction> {
|
||||
return factory(
|
||||
cache,
|
||||
"authRequestCryptoService",
|
||||
opts,
|
||||
async () => new AuthRequestCryptoServiceImplementation(await cryptoServiceFactory(cache, opts))
|
||||
async () => new AuthRequestCryptoServiceImplementation(await cryptoServiceFactory(cache, opts)),
|
||||
);
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ export type AuthServiceInitOptions = AuthServiceFactoyOptions &
|
||||
|
||||
export function authServiceFactory(
|
||||
cache: { authService?: AbstractAuthService } & CachedServices,
|
||||
opts: AuthServiceInitOptions
|
||||
opts: AuthServiceInitOptions,
|
||||
): Promise<AbstractAuthService> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -113,7 +113,7 @@ export function authServiceFactory(
|
||||
await passwordStrengthServiceFactory(cache, opts),
|
||||
await policyServiceFactory(cache, opts),
|
||||
await deviceTrustCryptoServiceFactory(cache, opts),
|
||||
await authRequestCryptoServiceFactory(cache, opts)
|
||||
)
|
||||
await authRequestCryptoServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ export type DeviceTrustCryptoServiceInitOptions = DeviceTrustCryptoServiceFactor
|
||||
|
||||
export function deviceTrustCryptoServiceFactory(
|
||||
cache: { deviceTrustCryptoService?: DeviceTrustCryptoServiceAbstraction } & CachedServices,
|
||||
opts: DeviceTrustCryptoServiceInitOptions
|
||||
opts: DeviceTrustCryptoServiceInitOptions,
|
||||
): Promise<DeviceTrustCryptoServiceAbstraction> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -68,7 +68,7 @@ export function deviceTrustCryptoServiceFactory(
|
||||
await appIdServiceFactory(cache, opts),
|
||||
await devicesApiServiceFactory(cache, opts),
|
||||
await i18nServiceFactory(cache, opts),
|
||||
await platformUtilsServiceFactory(cache, opts)
|
||||
)
|
||||
await platformUtilsServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ export type KeyConnectorServiceInitOptions = KeyConnectorServiceFactoryOptions &
|
||||
|
||||
export function keyConnectorServiceFactory(
|
||||
cache: { keyConnectorService?: AbstractKeyConnectorService } & CachedServices,
|
||||
opts: KeyConnectorServiceInitOptions
|
||||
opts: KeyConnectorServiceInitOptions,
|
||||
): Promise<AbstractKeyConnectorService> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -65,7 +65,7 @@ export function keyConnectorServiceFactory(
|
||||
await logServiceFactory(cache, opts),
|
||||
await organizationServiceFactory(cache, opts),
|
||||
await cryptoFunctionServiceFactory(cache, opts),
|
||||
opts.keyConnectorServiceOptions.logoutCallback
|
||||
)
|
||||
opts.keyConnectorServiceOptions.logoutCallback,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ export type TokenServiceInitOptions = TokenServiceFactoryOptions & StateServiceI
|
||||
|
||||
export function tokenServiceFactory(
|
||||
cache: { tokenService?: AbstractTokenService } & CachedServices,
|
||||
opts: TokenServiceInitOptions
|
||||
opts: TokenServiceInitOptions,
|
||||
): Promise<AbstractTokenService> {
|
||||
return factory(
|
||||
cache,
|
||||
"tokenService",
|
||||
opts,
|
||||
async () => new TokenService(await stateServiceFactory(cache, opts))
|
||||
async () => new TokenService(await stateServiceFactory(cache, opts)),
|
||||
);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ export type TwoFactorServiceInitOptions = TwoFactorServiceFactoryOptions &
|
||||
|
||||
export async function twoFactorServiceFactory(
|
||||
cache: { twoFactorService?: AbstractTwoFactorService } & CachedServices,
|
||||
opts: TwoFactorServiceInitOptions
|
||||
opts: TwoFactorServiceInitOptions,
|
||||
): Promise<AbstractTwoFactorService> {
|
||||
const service = await factory(
|
||||
cache,
|
||||
@ -32,8 +32,8 @@ export async function twoFactorServiceFactory(
|
||||
async () =>
|
||||
new TwoFactorService(
|
||||
await i18nServiceFactory(cache, opts),
|
||||
await platformUtilsServiceFactory(cache, opts)
|
||||
)
|
||||
await platformUtilsServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
service.init();
|
||||
return service;
|
||||
|
@ -18,12 +18,12 @@ export type UserVerificationApiServiceInitOptions = UserVerificationApiServiceFa
|
||||
|
||||
export function userVerificationApiServiceFactory(
|
||||
cache: { userVerificationApiService?: UserVerificationApiServiceAbstraction } & CachedServices,
|
||||
opts: UserVerificationApiServiceInitOptions
|
||||
opts: UserVerificationApiServiceInitOptions,
|
||||
): Promise<UserVerificationApiServiceAbstraction> {
|
||||
return factory(
|
||||
cache,
|
||||
"userVerificationApiService",
|
||||
opts,
|
||||
async () => new UserVerificationApiService(await apiServiceFactory(cache, opts))
|
||||
async () => new UserVerificationApiService(await apiServiceFactory(cache, opts)),
|
||||
);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ export type UserVerificationServiceInitOptions = UserVerificationServiceFactoryO
|
||||
|
||||
export function userVerificationServiceFactory(
|
||||
cache: { userVerificationService?: AbstractUserVerificationService } & CachedServices,
|
||||
opts: UserVerificationServiceInitOptions
|
||||
opts: UserVerificationServiceInitOptions,
|
||||
): Promise<AbstractUserVerificationService> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -45,7 +45,7 @@ export function userVerificationServiceFactory(
|
||||
await stateServiceFactory(cache, opts),
|
||||
await cryptoServiceFactory(cache, opts),
|
||||
await i18nServiceFactory(cache, opts),
|
||||
await userVerificationApiServiceFactory(cache, opts)
|
||||
)
|
||||
await userVerificationApiServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import { BrowserRouterService } from "../../platform/popup/services/browser-rout
|
||||
*/
|
||||
export const fido2AuthGuard: CanActivateFn = async (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot
|
||||
state: RouterStateSnapshot,
|
||||
) => {
|
||||
const routerService = inject(BrowserRouterService);
|
||||
const authService = inject(AuthService);
|
||||
|
@ -11,7 +11,7 @@ export class AccountSwitcherComponent {
|
||||
constructor(
|
||||
private accountSwitcherService: AccountSwitcherService,
|
||||
private router: Router,
|
||||
private routerService: BrowserRouterService
|
||||
private routerService: BrowserRouterService,
|
||||
) {}
|
||||
|
||||
get accountOptions$() {
|
||||
|
@ -10,7 +10,10 @@ import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
templateUrl: "current-account.component.html",
|
||||
})
|
||||
export class CurrentAccountComponent {
|
||||
constructor(private accountService: AccountService, private router: Router) {}
|
||||
constructor(
|
||||
private accountService: AccountService,
|
||||
private router: Router,
|
||||
) {}
|
||||
|
||||
get currentAccount$() {
|
||||
return this.accountService.activeAccount$;
|
||||
@ -20,7 +23,7 @@ export class CurrentAccountComponent {
|
||||
return this.currentAccount$.pipe(
|
||||
map((a) => {
|
||||
return Utils.isNullOrWhitespace(a.name) ? a.email : a.name;
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ export class EnvironmentComponent extends BaseEnvironmentComponent implements On
|
||||
public environmentService: BrowserEnvironmentService,
|
||||
i18nService: I18nService,
|
||||
private router: Router,
|
||||
modalService: ModalService
|
||||
modalService: ModalService,
|
||||
) {
|
||||
super(platformUtilsService, environmentService, i18nService, modalService);
|
||||
this.showCustom = true;
|
||||
|
@ -20,7 +20,7 @@ export class HintComponent extends BaseHintComponent {
|
||||
apiService: ApiService,
|
||||
logService: LogService,
|
||||
private route: ActivatedRoute,
|
||||
loginService: LoginService
|
||||
loginService: LoginService,
|
||||
) {
|
||||
super(router, i18nService, apiService, platformUtilsService, logService, loginService);
|
||||
|
||||
|
@ -32,7 +32,7 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||
private router: Router,
|
||||
private i18nService: I18nService,
|
||||
private environmentService: EnvironmentService,
|
||||
private loginService: LoginService
|
||||
private loginService: LoginService,
|
||||
) {}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
@ -73,7 +73,7 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
this.i18nService.t("errorOccured"),
|
||||
this.i18nService.t("invalidEmail")
|
||||
this.i18nService.t("invalidEmail"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@
|
||||
: ("yourVaultIsLocked" | i18n)
|
||||
}}
|
||||
</p>
|
||||
{{ "loggedInAsOn" | i18n : email : webVaultHostname }}
|
||||
{{ "loggedInAsOn" | i18n: email : webVaultHostname }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="box" *ngIf="biometricLock">
|
||||
|
@ -56,7 +56,7 @@ export class LockComponent extends BaseLockComponent {
|
||||
dialogService: DialogService,
|
||||
deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
|
||||
userVerificationService: UserVerificationService,
|
||||
private routerService: BrowserRouterService
|
||||
private routerService: BrowserRouterService,
|
||||
) {
|
||||
super(
|
||||
router,
|
||||
@ -76,7 +76,7 @@ export class LockComponent extends BaseLockComponent {
|
||||
passwordStrengthService,
|
||||
dialogService,
|
||||
deviceTrustCryptoService,
|
||||
userVerificationService
|
||||
userVerificationService,
|
||||
);
|
||||
this.successRoute = "/tabs/current";
|
||||
this.isInitialLockScreen = (window as any).previousPopupUrl == null;
|
||||
|
@ -48,7 +48,7 @@ export class LoginViaAuthRequestComponent
|
||||
syncService: SyncService,
|
||||
deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
|
||||
authReqCryptoService: AuthRequestCryptoServiceAbstraction,
|
||||
private location: Location
|
||||
private location: Location,
|
||||
) {
|
||||
super(
|
||||
router,
|
||||
@ -67,7 +67,7 @@ export class LoginViaAuthRequestComponent
|
||||
stateService,
|
||||
loginService,
|
||||
deviceTrustCryptoService,
|
||||
authReqCryptoService
|
||||
authReqCryptoService,
|
||||
);
|
||||
super.onSuccessfulLogin = async () => {
|
||||
await syncService.fullSync(true);
|
||||
|
@ -45,7 +45,7 @@ export class LoginComponent extends BaseLoginComponent {
|
||||
formValidationErrorService: FormValidationErrorsService,
|
||||
route: ActivatedRoute,
|
||||
loginService: LoginService,
|
||||
webAuthnLoginService: WebAuthnLoginServiceAbstraction
|
||||
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
||||
) {
|
||||
super(
|
||||
devicesApiService,
|
||||
@ -64,7 +64,7 @@ export class LoginComponent extends BaseLoginComponent {
|
||||
formValidationErrorService,
|
||||
route,
|
||||
loginService,
|
||||
webAuthnLoginService
|
||||
webAuthnLoginService,
|
||||
);
|
||||
super.onSuccessfulLogin = async () => {
|
||||
await syncService.fullSync(true);
|
||||
@ -123,7 +123,7 @@ export class LoginComponent extends BaseLoginComponent {
|
||||
"&codeChallenge=" +
|
||||
codeChallenge +
|
||||
"&email=" +
|
||||
encodeURIComponent(this.formGroup.controls.email.value)
|
||||
encodeURIComponent(this.formGroup.controls.email.value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ export class RegisterComponent extends BaseRegisterComponent {
|
||||
environmentService: EnvironmentService,
|
||||
logService: LogService,
|
||||
auditService: AuditService,
|
||||
dialogService: DialogService
|
||||
dialogService: DialogService,
|
||||
) {
|
||||
super(
|
||||
formValidationErrorService,
|
||||
@ -54,7 +54,7 @@ export class RegisterComponent extends BaseRegisterComponent {
|
||||
environmentService,
|
||||
logService,
|
||||
auditService,
|
||||
dialogService
|
||||
dialogService,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<p>{{ "convertOrganizationEncryptionDesc" | i18n : organization.name }}</p>
|
||||
<p>{{ "convertOrganizationEncryptionDesc" | i18n: organization.name }}</p>
|
||||
</div>
|
||||
<div class="box-content-row">
|
||||
<button
|
||||
|
@ -26,7 +26,7 @@ describe("AccountSwitcherService", () => {
|
||||
accountSwitcherService = new AccountSwitcherService(
|
||||
accountService,
|
||||
stateService,
|
||||
messagingService
|
||||
messagingService,
|
||||
);
|
||||
});
|
||||
|
||||
@ -45,7 +45,7 @@ describe("AccountSwitcherService", () => {
|
||||
activeAccountSubject.next(Object.assign(user1AccountInfo, { id: "1" as UserId }));
|
||||
|
||||
const accounts = await firstValueFrom(
|
||||
accountSwitcherService.accountOptions$.pipe(timeout(20))
|
||||
accountSwitcherService.accountOptions$.pipe(timeout(20)),
|
||||
);
|
||||
expect(accounts).toHaveLength(2);
|
||||
expect(accounts[0].id).toBe("1");
|
||||
@ -68,7 +68,7 @@ describe("AccountSwitcherService", () => {
|
||||
}
|
||||
accountsSubject.next(seedAccounts);
|
||||
activeAccountSubject.next(
|
||||
Object.assign(seedAccounts["1" as UserId], { id: "1" as UserId })
|
||||
Object.assign(seedAccounts["1" as UserId], { id: "1" as UserId }),
|
||||
);
|
||||
|
||||
const accounts = await firstValueFrom(accountSwitcherService.accountOptions$);
|
||||
@ -77,7 +77,7 @@ describe("AccountSwitcherService", () => {
|
||||
accounts.forEach((account) => {
|
||||
expect(account.id).not.toBe("addAccount");
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@ -99,7 +99,7 @@ describe("AccountSwitcherService", () => {
|
||||
"switchAccount",
|
||||
matches((payload) => {
|
||||
return payload.userId === "1";
|
||||
})
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -15,7 +15,7 @@ export class AccountSwitcherService {
|
||||
constructor(
|
||||
private accountService: AccountService,
|
||||
private stateService: StateService,
|
||||
private messagingService: MessagingService
|
||||
private messagingService: MessagingService,
|
||||
) {}
|
||||
|
||||
get accountOptions$() {
|
||||
@ -31,7 +31,7 @@ export class AccountSwitcherService {
|
||||
id: id,
|
||||
isSelected: id === activeAccount?.id,
|
||||
};
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (!hasMaxAccounts) {
|
||||
@ -43,7 +43,7 @@ export class AccountSwitcherService {
|
||||
}
|
||||
|
||||
return options;
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ export class SetPasswordComponent extends BaseSetPasswordComponent {
|
||||
route: ActivatedRoute,
|
||||
organizationApiService: OrganizationApiServiceAbstraction,
|
||||
organizationUserService: OrganizationUserService,
|
||||
dialogService: DialogService
|
||||
dialogService: DialogService,
|
||||
) {
|
||||
super(
|
||||
i18nService,
|
||||
@ -53,7 +53,7 @@ export class SetPasswordComponent extends BaseSetPasswordComponent {
|
||||
stateService,
|
||||
organizationApiService,
|
||||
organizationUserService,
|
||||
dialogService
|
||||
dialogService,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||
environmentService: EnvironmentService,
|
||||
logService: LogService,
|
||||
configService: ConfigServiceAbstraction,
|
||||
@Inject(WINDOW) private win: Window
|
||||
@Inject(WINDOW) private win: Window,
|
||||
) {
|
||||
super(
|
||||
authService,
|
||||
@ -51,7 +51,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||
environmentService,
|
||||
passwordGenerationService,
|
||||
logService,
|
||||
configService
|
||||
configService,
|
||||
);
|
||||
|
||||
const url = this.environmentService.getWebVaultUrl();
|
||||
|
@ -16,7 +16,7 @@ export class TwoFactorOptionsComponent extends BaseTwoFactorOptionsComponent {
|
||||
router: Router,
|
||||
i18nService: I18nService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
private activatedRoute: ActivatedRoute
|
||||
private activatedRoute: ActivatedRoute,
|
||||
) {
|
||||
super(twoFactorService, router, i18nService, platformUtilsService, window);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
{{ "enterVerificationCodeApp" | i18n }}
|
||||
</span>
|
||||
<span *ngIf="selectedProviderType === providerType.Email">
|
||||
{{ "enterVerificationCodeEmail" | i18n : twoFactorEmail }}
|
||||
{{ "enterVerificationCodeEmail" | i18n: twoFactorEmail }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="box first">
|
||||
|
@ -51,7 +51,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
||||
loginService: LoginService,
|
||||
configService: ConfigServiceAbstraction,
|
||||
private dialogService: DialogService,
|
||||
@Inject(WINDOW) protected win: Window
|
||||
@Inject(WINDOW) protected win: Window,
|
||||
) {
|
||||
super(
|
||||
authService,
|
||||
@ -67,7 +67,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
||||
twoFactorService,
|
||||
appIdService,
|
||||
loginService,
|
||||
configService
|
||||
configService,
|
||||
);
|
||||
super.onSuccessfulLogin = async () => {
|
||||
syncService.fullSync(true);
|
||||
|
@ -103,7 +103,7 @@ describe("AuthPopoutWindow", () => {
|
||||
|
||||
expect(openPopoutSpy).toHaveBeenCalledWith(
|
||||
"popup/index.html#/2fa;webAuthnResponse=data;remember=remember",
|
||||
{ singleActionKey: AuthPopoutType.twoFactorAuth }
|
||||
{ singleActionKey: AuthPopoutType.twoFactorAuth },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -47,7 +47,7 @@ async function closeUnlockPopout() {
|
||||
async function openSsoAuthResultPopout(resultData: { code: string; state: string }) {
|
||||
const { code, state } = resultData;
|
||||
const authResultUrl = `popup/index.html#/sso?code=${encodeURIComponent(
|
||||
code
|
||||
code,
|
||||
)}&state=${encodeURIComponent(state)}`;
|
||||
|
||||
await BrowserPopupUtils.openPopout(authResultUrl, {
|
||||
|
@ -15,14 +15,14 @@ export default class ContextMenusBackground {
|
||||
}
|
||||
|
||||
this.contextMenus.onClicked.addListener((info, tab) =>
|
||||
this.contextMenuClickedHandler.run(info, tab)
|
||||
this.contextMenuClickedHandler.run(info, tab),
|
||||
);
|
||||
|
||||
BrowserApi.messageListener(
|
||||
"contextmenus.background",
|
||||
(
|
||||
msg: { command: string; data: LockedVaultPendingNotificationsItem },
|
||||
sender: chrome.runtime.MessageSender
|
||||
sender: chrome.runtime.MessageSender,
|
||||
) => {
|
||||
if (msg.command === "unlockCompleted" && msg.data.target === "contextmenus.background") {
|
||||
this.contextMenuClickedHandler
|
||||
@ -31,7 +31,7 @@ export default class ContextMenusBackground {
|
||||
BrowserApi.tabSendMessageData(sender.tab, "closeNotificationBar");
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ describe("NotificationBackground", () => {
|
||||
policyService,
|
||||
folderService,
|
||||
stateService,
|
||||
environmentService
|
||||
environmentService,
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -40,7 +40,7 @@ export default class NotificationBackground {
|
||||
private policyService: PolicyService,
|
||||
private folderService: FolderService,
|
||||
private stateService: BrowserStateService,
|
||||
private environmentService: EnvironmentService
|
||||
private environmentService: EnvironmentService,
|
||||
) {}
|
||||
|
||||
async init() {
|
||||
@ -52,7 +52,7 @@ export default class NotificationBackground {
|
||||
"notification.background",
|
||||
(msg: any, sender: chrome.runtime.MessageSender) => {
|
||||
this.processMessage(msg, sender);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
this.cleanupNotificationQueue();
|
||||
@ -97,7 +97,7 @@ export default class NotificationBackground {
|
||||
await BrowserApi.tabSendMessageData(
|
||||
sender.tab,
|
||||
"addToLockedVaultPendingNotifications",
|
||||
retryMessage
|
||||
retryMessage,
|
||||
);
|
||||
await openUnlockPopout(sender.tab);
|
||||
return;
|
||||
@ -259,7 +259,7 @@ export default class NotificationBackground {
|
||||
|
||||
const ciphers = await this.cipherService.getAllDecryptedForUrl(loginInfo.url);
|
||||
const usernameMatches = ciphers.filter(
|
||||
(c) => c.login.username != null && c.login.username.toLowerCase() === normalizedUsername
|
||||
(c) => c.login.username != null && c.login.username.toLowerCase() === normalizedUsername,
|
||||
);
|
||||
if (usernameMatches.length === 0) {
|
||||
if (disabledAddLogin) {
|
||||
@ -284,7 +284,7 @@ export default class NotificationBackground {
|
||||
loginDomain: string,
|
||||
loginInfo: AddLoginRuntimeMessage,
|
||||
tab: chrome.tabs.Tab,
|
||||
isVaultLocked = false
|
||||
isVaultLocked = false,
|
||||
) {
|
||||
// remove any old messages for this tab
|
||||
this.removeTabFromNotificationQueue(tab);
|
||||
@ -317,7 +317,7 @@ export default class NotificationBackground {
|
||||
const ciphers = await this.cipherService.getAllDecryptedForUrl(changeData.url);
|
||||
if (changeData.currentPassword != null) {
|
||||
const passwordMatches = ciphers.filter(
|
||||
(c) => c.login.password === changeData.currentPassword
|
||||
(c) => c.login.password === changeData.currentPassword,
|
||||
);
|
||||
if (passwordMatches.length === 1) {
|
||||
id = passwordMatches[0].id;
|
||||
@ -339,7 +339,7 @@ export default class NotificationBackground {
|
||||
*/
|
||||
private async unlockVault(
|
||||
message: { data?: { skipNotification?: boolean } },
|
||||
tab: chrome.tabs.Tab
|
||||
tab: chrome.tabs.Tab,
|
||||
) {
|
||||
if (message.data?.skipNotification) {
|
||||
return;
|
||||
@ -363,7 +363,7 @@ export default class NotificationBackground {
|
||||
loginDomain: string,
|
||||
newPassword: string,
|
||||
tab: chrome.tabs.Tab,
|
||||
isVaultLocked = false
|
||||
isVaultLocked = false,
|
||||
) {
|
||||
// remove any old messages for this tab
|
||||
this.removeTabFromNotificationQueue(tab);
|
||||
@ -421,7 +421,7 @@ export default class NotificationBackground {
|
||||
const allCiphers = await this.cipherService.getAllDecryptedForUrl(queueMessage.uri);
|
||||
const existingCipher = allCiphers.find(
|
||||
(c) =>
|
||||
c.login.username != null && c.login.username.toLowerCase() === queueMessage.username
|
||||
c.login.username != null && c.login.username.toLowerCase() === queueMessage.username,
|
||||
);
|
||||
|
||||
if (existingCipher != null) {
|
||||
@ -449,7 +449,7 @@ export default class NotificationBackground {
|
||||
cipherView: CipherView,
|
||||
newPassword: string,
|
||||
edit: boolean,
|
||||
tab: chrome.tabs.Tab
|
||||
tab: chrome.tabs.Tab,
|
||||
) {
|
||||
cipherView.login.password = newPassword;
|
||||
|
||||
@ -525,13 +525,13 @@ export default class NotificationBackground {
|
||||
|
||||
private async removeIndividualVault(): Promise<boolean> {
|
||||
return await firstValueFrom(
|
||||
this.policyService.policyAppliesToActiveUser$(PolicyType.PersonalOwnership)
|
||||
this.policyService.policyAppliesToActiveUser$(PolicyType.PersonalOwnership),
|
||||
);
|
||||
}
|
||||
|
||||
private async handleUnlockCompleted(
|
||||
messageData: LockedVaultPendingNotificationsItem,
|
||||
sender: chrome.runtime.MessageSender
|
||||
sender: chrome.runtime.MessageSender,
|
||||
): Promise<void> {
|
||||
if (messageData.commandToRetry.msg.command === "autofill_login") {
|
||||
await BrowserApi.tabSendMessageData(sender.tab, "closeNotificationBar");
|
||||
@ -543,7 +543,7 @@ export default class NotificationBackground {
|
||||
|
||||
await this.processMessage(
|
||||
messageData.commandToRetry.msg.command,
|
||||
messageData.commandToRetry.sender
|
||||
messageData.commandToRetry.sender,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ describe("OverlayBackground", () => {
|
||||
environmentService,
|
||||
settingsService,
|
||||
stateService,
|
||||
i18nService
|
||||
i18nService,
|
||||
);
|
||||
overlayBackground.init();
|
||||
});
|
||||
@ -163,7 +163,7 @@ describe("OverlayBackground", () => {
|
||||
new Map([
|
||||
["overlay-cipher-0", cipher2],
|
||||
["overlay-cipher-1", cipher1],
|
||||
])
|
||||
]),
|
||||
);
|
||||
expect(overlayBackground["getOverlayCipherData"]).toHaveBeenCalled();
|
||||
});
|
||||
@ -219,7 +219,7 @@ describe("OverlayBackground", () => {
|
||||
expect(BrowserApi.tabSendMessageData).toHaveBeenCalledWith(
|
||||
tab,
|
||||
"updateIsOverlayCiphersPopulated",
|
||||
{ isOverlayCiphersPopulated: true }
|
||||
{ isOverlayCiphersPopulated: true },
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -489,7 +489,7 @@ describe("OverlayBackground", () => {
|
||||
const returnValue = overlayBackground["handleExtensionMessage"](
|
||||
message,
|
||||
sender,
|
||||
sendResponse
|
||||
sendResponse,
|
||||
);
|
||||
|
||||
expect(returnValue).toBe(undefined);
|
||||
@ -507,7 +507,7 @@ describe("OverlayBackground", () => {
|
||||
const returnValue = overlayBackground["handleExtensionMessage"](
|
||||
message,
|
||||
sender,
|
||||
sendResponse
|
||||
sendResponse,
|
||||
);
|
||||
|
||||
expect(returnValue).toBe(undefined);
|
||||
@ -526,7 +526,7 @@ describe("OverlayBackground", () => {
|
||||
const returnValue = overlayBackground["handleExtensionMessage"](
|
||||
message,
|
||||
sender,
|
||||
sendResponse
|
||||
sendResponse,
|
||||
);
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
@ -555,7 +555,7 @@ describe("OverlayBackground", () => {
|
||||
isFocusingFieldElement: false,
|
||||
isOpeningFullOverlay: false,
|
||||
authStatus: AuthenticationStatus.Unlocked,
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -614,7 +614,7 @@ describe("OverlayBackground", () => {
|
||||
password: "password",
|
||||
},
|
||||
},
|
||||
sender
|
||||
sender,
|
||||
);
|
||||
await flushPromises();
|
||||
|
||||
@ -635,7 +635,7 @@ describe("OverlayBackground", () => {
|
||||
await flushPromises();
|
||||
|
||||
expect(overlayBackground["overlayVisibility"]).toBe(
|
||||
AutofillOverlayVisibility.OnFieldFocus
|
||||
AutofillOverlayVisibility.OnFieldFocus,
|
||||
);
|
||||
});
|
||||
|
||||
@ -645,7 +645,7 @@ describe("OverlayBackground", () => {
|
||||
sendExtensionRuntimeMessage(
|
||||
{ command: "getAutofillOverlayVisibility" },
|
||||
undefined,
|
||||
sendMessageSpy
|
||||
sendMessageSpy,
|
||||
);
|
||||
await flushPromises();
|
||||
|
||||
@ -851,7 +851,7 @@ describe("OverlayBackground", () => {
|
||||
it("stores the page details provided by the message by the tab id of the sender", () => {
|
||||
sendExtensionRuntimeMessage(
|
||||
{ command: "collectPageDetailsResponse", details: pageDetails1 },
|
||||
sender
|
||||
sender,
|
||||
);
|
||||
|
||||
expect(overlayBackground["pageDetailsForTab"][sender.tab.id]).toStrictEqual([
|
||||
@ -870,7 +870,7 @@ describe("OverlayBackground", () => {
|
||||
|
||||
sendExtensionRuntimeMessage(
|
||||
{ command: "collectPageDetailsResponse", details: pageDetails2 },
|
||||
sender
|
||||
sender,
|
||||
);
|
||||
|
||||
expect(overlayBackground["pageDetailsForTab"][sender.tab.id]).toStrictEqual([
|
||||
@ -930,7 +930,7 @@ describe("OverlayBackground", () => {
|
||||
isFocusingFieldElement: true,
|
||||
isOpeningFullOverlay: false,
|
||||
authStatus: AuthenticationStatus.Unlocked,
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1096,7 +1096,7 @@ describe("OverlayBackground", () => {
|
||||
expect(BrowserApi.tabSendMessageData).toHaveBeenCalledWith(
|
||||
buttonPortSpy.sender.tab,
|
||||
"redirectOverlayFocusOut",
|
||||
{ direction: RedirectFocusDirection.Next }
|
||||
{ direction: RedirectFocusDirection.Next },
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1142,11 +1142,11 @@ describe("OverlayBackground", () => {
|
||||
sender: listPortSpy.sender,
|
||||
},
|
||||
target: "overlay.background",
|
||||
}
|
||||
},
|
||||
);
|
||||
expect(overlayBackground["openUnlockPopout"]).toHaveBeenCalledWith(
|
||||
listPortSpy.sender.tab,
|
||||
true
|
||||
true,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1160,7 +1160,7 @@ describe("OverlayBackground", () => {
|
||||
getLoginCiphersSpy = jest.spyOn(overlayBackground["overlayLoginCiphers"], "get");
|
||||
isPasswordRepromptRequiredSpy = jest.spyOn(
|
||||
overlayBackground["autofillService"],
|
||||
"isPasswordRepromptRequired"
|
||||
"isPasswordRepromptRequired",
|
||||
);
|
||||
doAutoFillSpy = jest.spyOn(overlayBackground["autofillService"], "doAutoFill");
|
||||
});
|
||||
@ -1192,7 +1192,7 @@ describe("OverlayBackground", () => {
|
||||
expect(getLoginCiphersSpy).toHaveBeenCalled();
|
||||
expect(isPasswordRepromptRequiredSpy).toHaveBeenCalledWith(
|
||||
cipher,
|
||||
listPortSpy.sender.tab
|
||||
listPortSpy.sender.tab,
|
||||
);
|
||||
expect(doAutoFillSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
@ -1216,7 +1216,7 @@ describe("OverlayBackground", () => {
|
||||
|
||||
expect(isPasswordRepromptRequiredSpy).toHaveBeenCalledWith(
|
||||
cipher2,
|
||||
listPortSpy.sender.tab
|
||||
listPortSpy.sender.tab,
|
||||
);
|
||||
expect(doAutoFillSpy).toHaveBeenCalledWith({
|
||||
tab: listPortSpy.sender.tab,
|
||||
@ -1230,7 +1230,7 @@ describe("OverlayBackground", () => {
|
||||
["overlay-cipher-2", cipher2],
|
||||
["overlay-cipher-1", cipher1],
|
||||
["overlay-cipher-3", cipher3],
|
||||
]).entries()
|
||||
]).entries(),
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1289,7 +1289,7 @@ describe("OverlayBackground", () => {
|
||||
{
|
||||
cipherId: cipher.id,
|
||||
action: SHOW_AUTOFILL_BUTTON,
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1302,7 +1302,7 @@ describe("OverlayBackground", () => {
|
||||
};
|
||||
const redirectOverlayFocusOutSpy = jest.spyOn(
|
||||
overlayBackground as any,
|
||||
"redirectOverlayFocusOut"
|
||||
"redirectOverlayFocusOut",
|
||||
);
|
||||
|
||||
sendPortMessage(listPortSpy, message);
|
||||
|
@ -88,7 +88,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
private environmentService: EnvironmentService,
|
||||
private settingsService: SettingsService,
|
||||
private stateService: StateService,
|
||||
private i18nService: I18nService
|
||||
private i18nService: I18nService,
|
||||
) {
|
||||
this.iconsServerUrl = this.environmentService.getIconsUrl();
|
||||
}
|
||||
@ -130,7 +130,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
|
||||
this.overlayLoginCiphers = new Map();
|
||||
const ciphersViews = (await this.cipherService.getAllDecryptedForUrl(currentTab.url)).sort(
|
||||
(a, b) => this.cipherService.sortCiphersByLastUsedThenName(a, b)
|
||||
(a, b) => this.cipherService.sortCiphersByLastUsedThenName(a, b),
|
||||
);
|
||||
for (let cipherIndex = 0; cipherIndex < ciphersViews.length; cipherIndex++) {
|
||||
this.overlayLoginCiphers.set(`overlay-cipher-${cipherIndex}`, ciphersViews[cipherIndex]);
|
||||
@ -189,7 +189,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
*/
|
||||
private storePageDetails(
|
||||
message: OverlayBackgroundExtensionMessage,
|
||||
sender: chrome.runtime.MessageSender
|
||||
sender: chrome.runtime.MessageSender,
|
||||
) {
|
||||
const pageDetails = {
|
||||
frameId: sender.frameId,
|
||||
@ -214,7 +214,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
*/
|
||||
private async fillSelectedOverlayListItem(
|
||||
{ overlayCipherId }: OverlayPortMessage,
|
||||
{ sender }: chrome.runtime.Port
|
||||
{ sender }: chrome.runtime.Port,
|
||||
) {
|
||||
if (!overlayCipherId) {
|
||||
return;
|
||||
@ -528,7 +528,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
await BrowserApi.tabSendMessageData(
|
||||
sender.tab,
|
||||
"addToLockedVaultPendingNotifications",
|
||||
retryMessage
|
||||
retryMessage,
|
||||
);
|
||||
await this.openUnlockPopout(sender.tab, true);
|
||||
}
|
||||
@ -541,7 +541,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
*/
|
||||
private async viewSelectedCipher(
|
||||
{ overlayCipherId }: OverlayPortMessage,
|
||||
{ sender }: chrome.runtime.Port
|
||||
{ sender }: chrome.runtime.Port,
|
||||
) {
|
||||
const cipher = this.overlayLoginCiphers.get(overlayCipherId);
|
||||
if (!cipher) {
|
||||
@ -609,7 +609,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
*/
|
||||
private redirectOverlayFocusOut(
|
||||
{ direction }: OverlayPortMessage,
|
||||
{ sender }: chrome.runtime.Port
|
||||
{ sender }: chrome.runtime.Port,
|
||||
) {
|
||||
if (!direction) {
|
||||
return;
|
||||
@ -637,7 +637,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
*/
|
||||
private async addNewVaultItem(
|
||||
{ login }: OverlayAddNewItemMessage,
|
||||
sender: chrome.runtime.MessageSender
|
||||
sender: chrome.runtime.MessageSender,
|
||||
) {
|
||||
if (!login) {
|
||||
return;
|
||||
@ -683,7 +683,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
private handleExtensionMessage = (
|
||||
message: OverlayBackgroundExtensionMessage,
|
||||
sender: chrome.runtime.MessageSender,
|
||||
sendResponse: (response?: any) => void
|
||||
sendResponse: (response?: any) => void,
|
||||
) => {
|
||||
const handler: CallableFunction | undefined = this.extensionMessageHandlers[message?.command];
|
||||
if (!handler) {
|
||||
@ -742,7 +742,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
*/
|
||||
private handleOverlayElementPortMessage = (
|
||||
message: OverlayBackgroundExtensionMessage,
|
||||
port: chrome.runtime.Port
|
||||
port: chrome.runtime.Port,
|
||||
) => {
|
||||
const command = message?.command;
|
||||
let handler: CallableFunction | undefined;
|
||||
|
@ -47,7 +47,7 @@ export type AutoFillServiceInitOptions = AutoFillServiceOptions &
|
||||
|
||||
export function autofillServiceFactory(
|
||||
cache: { autofillService?: AbstractAutoFillService } & CachedServices,
|
||||
opts: AutoFillServiceInitOptions
|
||||
opts: AutoFillServiceInitOptions,
|
||||
): Promise<AbstractAutoFillService> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -61,7 +61,7 @@ export function autofillServiceFactory(
|
||||
await eventCollectionServiceFactory(cache, opts),
|
||||
await logServiceFactory(cache, opts),
|
||||
await settingsServiceFactory(cache, opts),
|
||||
await userVerificationServiceFactory(cache, opts)
|
||||
)
|
||||
await userVerificationServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -36,13 +36,13 @@ describe("TabsBackground", () => {
|
||||
it("sets up a window on focusChanged listener", () => {
|
||||
const handleWindowOnFocusChangedSpy = jest.spyOn(
|
||||
tabsBackgorund as any,
|
||||
"handleWindowOnFocusChanged"
|
||||
"handleWindowOnFocusChanged",
|
||||
);
|
||||
|
||||
tabsBackgorund.init();
|
||||
|
||||
expect(chrome.windows.onFocusChanged.addListener).toHaveBeenCalledWith(
|
||||
handleWindowOnFocusChangedSpy
|
||||
handleWindowOnFocusChangedSpy,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -7,7 +7,7 @@ export default class TabsBackground {
|
||||
constructor(
|
||||
private main: MainBackground,
|
||||
private notificationBackground: NotificationBackground,
|
||||
private overlayBackground: OverlayBackground
|
||||
private overlayBackground: OverlayBackground,
|
||||
) {}
|
||||
|
||||
private focusedWindowId: number;
|
||||
@ -74,7 +74,7 @@ export default class TabsBackground {
|
||||
private handleTabOnUpdated = async (
|
||||
tabId: number,
|
||||
changeInfo: chrome.tabs.TabChangeInfo,
|
||||
tab: chrome.tabs.Tab
|
||||
tab: chrome.tabs.Tab,
|
||||
) => {
|
||||
const removePageDetailsStatus = new Set(["loading", "unloaded"]);
|
||||
if (removePageDetailsStatus.has(changeInfo.status)) {
|
||||
|
@ -120,19 +120,19 @@ describe("CipherContextMenuHandler", () => {
|
||||
expect(mainContextMenuHandler.loadOptions).toHaveBeenCalledWith(
|
||||
"Test Cipher (Test Username)",
|
||||
"5",
|
||||
loginCipher
|
||||
loginCipher,
|
||||
);
|
||||
|
||||
expect(mainContextMenuHandler.loadOptions).toHaveBeenCalledWith(
|
||||
"Test Reprompt Cipher (Test Username)",
|
||||
"6",
|
||||
repromptLoginCipher
|
||||
repromptLoginCipher,
|
||||
);
|
||||
|
||||
expect(mainContextMenuHandler.loadOptions).toHaveBeenCalledWith(
|
||||
"Test Card Cipher",
|
||||
"7",
|
||||
cardCipher
|
||||
cardCipher,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -38,7 +38,7 @@ export class CipherContextMenuHandler {
|
||||
constructor(
|
||||
private mainContextMenuHandler: MainContextMenuHandler,
|
||||
private authService: AuthService,
|
||||
private cipherService: CipherService
|
||||
private cipherService: CipherService,
|
||||
) {}
|
||||
|
||||
static async create(cachedServices: CachedServices) {
|
||||
@ -74,7 +74,7 @@ export class CipherContextMenuHandler {
|
||||
return new CipherContextMenuHandler(
|
||||
await MainContextMenuHandler.mv3Create(cachedServices),
|
||||
await authServiceFactory(cachedServices, serviceOptions),
|
||||
await cipherServiceFactory(cachedServices, serviceOptions)
|
||||
await cipherServiceFactory(cachedServices, serviceOptions),
|
||||
);
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ export class CipherContextMenuHandler {
|
||||
|
||||
static async tabsOnActivatedListener(
|
||||
activeInfo: chrome.tabs.TabActiveInfo,
|
||||
serviceCache: CachedServices
|
||||
serviceCache: CachedServices,
|
||||
) {
|
||||
const cipherContextMenuHandler = await CipherContextMenuHandler.create(serviceCache);
|
||||
const tab = await BrowserApi.getTab(activeInfo.tabId);
|
||||
@ -96,7 +96,7 @@ export class CipherContextMenuHandler {
|
||||
static async tabsOnReplacedListener(
|
||||
addedTabId: number,
|
||||
removedTabId: number,
|
||||
serviceCache: CachedServices
|
||||
serviceCache: CachedServices,
|
||||
) {
|
||||
const cipherContextMenuHandler = await CipherContextMenuHandler.create(serviceCache);
|
||||
const tab = await BrowserApi.getTab(addedTabId);
|
||||
@ -107,7 +107,7 @@ export class CipherContextMenuHandler {
|
||||
tabId: number,
|
||||
changeInfo: chrome.tabs.TabChangeInfo,
|
||||
tab: chrome.tabs.Tab,
|
||||
serviceCache: CachedServices
|
||||
serviceCache: CachedServices,
|
||||
) {
|
||||
if (changeInfo.status !== "complete") {
|
||||
return;
|
||||
@ -119,7 +119,7 @@ export class CipherContextMenuHandler {
|
||||
static async messageListener(
|
||||
message: { command: string },
|
||||
sender: chrome.runtime.MessageSender,
|
||||
cachedServices: CachedServices
|
||||
cachedServices: CachedServices,
|
||||
) {
|
||||
if (!CipherContextMenuHandler.shouldListen(message)) {
|
||||
return;
|
||||
@ -183,7 +183,7 @@ export class CipherContextMenuHandler {
|
||||
[CipherType.Login]: [],
|
||||
[CipherType.Card]: [],
|
||||
[CipherType.Identity]: [],
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (groupedCiphers[CipherType.Login].length === 0) {
|
||||
|
@ -31,7 +31,7 @@ import {
|
||||
describe("ContextMenuClickedHandler", () => {
|
||||
const createData = (
|
||||
menuItemId: chrome.contextMenus.OnClickData["menuItemId"],
|
||||
parentMenuItemId?: chrome.contextMenus.OnClickData["parentMenuItemId"]
|
||||
parentMenuItemId?: chrome.contextMenus.OnClickData["parentMenuItemId"],
|
||||
): chrome.contextMenus.OnClickData => {
|
||||
return {
|
||||
menuItemId: menuItemId,
|
||||
@ -52,7 +52,7 @@ describe("ContextMenuClickedHandler", () => {
|
||||
new Cipher({
|
||||
id: id ?? "1",
|
||||
type: CipherType.Login,
|
||||
} as any)
|
||||
} as any),
|
||||
);
|
||||
|
||||
cipherView.login.username = username ?? "USERNAME";
|
||||
@ -92,7 +92,7 @@ describe("ContextMenuClickedHandler", () => {
|
||||
stateService,
|
||||
totpService,
|
||||
eventCollectionService,
|
||||
userVerificationService
|
||||
userVerificationService,
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -72,7 +72,7 @@ export class ContextMenuClickedHandler {
|
||||
private stateService: StateService,
|
||||
private totpService: TotpService,
|
||||
private eventCollectionService: EventCollectionService,
|
||||
private userVerificationService: UserVerificationService
|
||||
private userVerificationService: UserVerificationService,
|
||||
) {}
|
||||
|
||||
static async mv3Create(cachedServices: CachedServices) {
|
||||
@ -108,11 +108,11 @@ export class ContextMenuClickedHandler {
|
||||
|
||||
const generatePasswordToClipboardCommand = new GeneratePasswordToClipboardCommand(
|
||||
await passwordGenerationServiceFactory(cachedServices, serviceOptions),
|
||||
await stateServiceFactory(cachedServices, serviceOptions)
|
||||
await stateServiceFactory(cachedServices, serviceOptions),
|
||||
);
|
||||
|
||||
const autofillCommand = new AutofillTabCommand(
|
||||
await autofillServiceFactory(cachedServices, serviceOptions)
|
||||
await autofillServiceFactory(cachedServices, serviceOptions),
|
||||
);
|
||||
|
||||
return new ContextMenuClickedHandler(
|
||||
@ -124,14 +124,14 @@ export class ContextMenuClickedHandler {
|
||||
await stateServiceFactory(cachedServices, serviceOptions),
|
||||
await totpServiceFactory(cachedServices, serviceOptions),
|
||||
await eventCollectionServiceFactory(cachedServices, serviceOptions),
|
||||
await userVerificationServiceFactory(cachedServices, serviceOptions)
|
||||
await userVerificationServiceFactory(cachedServices, serviceOptions),
|
||||
);
|
||||
}
|
||||
|
||||
static async onClickedListener(
|
||||
info: chrome.contextMenus.OnClickData,
|
||||
tab?: chrome.tabs.Tab,
|
||||
cachedServices: CachedServices = {}
|
||||
cachedServices: CachedServices = {},
|
||||
) {
|
||||
const contextMenuClickedHandler = await ContextMenuClickedHandler.mv3Create(cachedServices);
|
||||
await contextMenuClickedHandler.run(info, tab);
|
||||
@ -140,7 +140,7 @@ export class ContextMenuClickedHandler {
|
||||
static async messageListener(
|
||||
message: { command: string; data: LockedVaultPendingNotificationsItem },
|
||||
sender: chrome.runtime.MessageSender,
|
||||
cachedServices: CachedServices
|
||||
cachedServices: CachedServices,
|
||||
) {
|
||||
if (
|
||||
message.command !== "unlockCompleted" ||
|
||||
@ -152,7 +152,7 @@ export class ContextMenuClickedHandler {
|
||||
const contextMenuClickedHandler = await ContextMenuClickedHandler.mv3Create(cachedServices);
|
||||
await contextMenuClickedHandler.run(
|
||||
message.data.commandToRetry.msg.data,
|
||||
message.data.commandToRetry.sender.tab
|
||||
message.data.commandToRetry.sender.tab,
|
||||
);
|
||||
}
|
||||
|
||||
@ -189,7 +189,7 @@ export class ContextMenuClickedHandler {
|
||||
await BrowserApi.tabSendMessageData(
|
||||
tab,
|
||||
"addToLockedVaultPendingNotifications",
|
||||
retryMessage
|
||||
retryMessage,
|
||||
);
|
||||
|
||||
await openUnlockPopout(tab);
|
||||
@ -201,7 +201,7 @@ export class ContextMenuClickedHandler {
|
||||
const menuItemId = (info.menuItemId as string).split("_")[1]; // We create all the ids, we can guarantee they are strings
|
||||
let cipher: CipherView | undefined;
|
||||
const isCreateCipherAction = [CREATE_LOGIN_ID, CREATE_IDENTITY_ID, CREATE_CARD_ID].includes(
|
||||
menuItemId as string
|
||||
menuItemId as string,
|
||||
);
|
||||
|
||||
if (isCreateCipherAction) {
|
||||
@ -211,15 +211,15 @@ export class ContextMenuClickedHandler {
|
||||
info.parentMenuItemId === AUTOFILL_IDENTITY_ID
|
||||
? [CipherType.Identity]
|
||||
: info.parentMenuItemId === AUTOFILL_CARD_ID
|
||||
? [CipherType.Card]
|
||||
: [];
|
||||
? [CipherType.Card]
|
||||
: [];
|
||||
|
||||
// This NOOP item has come through which is generally only for no access state but since we got here
|
||||
// we are actually unlocked we will do our best to find a good match of an item to autofill this is useful
|
||||
// in scenarios like unlock on autofill
|
||||
const ciphers = await this.cipherService.getAllDecryptedForUrl(
|
||||
tab.url,
|
||||
additionalCiphersToGet
|
||||
additionalCiphersToGet,
|
||||
);
|
||||
|
||||
cipher = ciphers[0];
|
||||
@ -314,10 +314,10 @@ export class ContextMenuClickedHandler {
|
||||
return menuItemId === CREATE_IDENTITY_ID
|
||||
? CipherType.Identity
|
||||
: menuItemId === CREATE_CARD_ID
|
||||
? CipherType.Card
|
||||
: menuItemId === CREATE_LOGIN_ID
|
||||
? CipherType.Login
|
||||
: null;
|
||||
? CipherType.Card
|
||||
: menuItemId === CREATE_LOGIN_ID
|
||||
? CipherType.Login
|
||||
: null;
|
||||
}
|
||||
|
||||
private async getIdentifier(tab: chrome.tabs.Tab, info: chrome.contextMenus.OnClickData) {
|
||||
@ -333,7 +333,7 @@ export class ContextMenuClickedHandler {
|
||||
}
|
||||
|
||||
resolve(identifier);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ describe("context-menu", () => {
|
||||
id: id ?? "1",
|
||||
type: CipherType.Login,
|
||||
viewPassword: viewPassword ?? true,
|
||||
} as any)
|
||||
} as any),
|
||||
);
|
||||
cipherView.login.username = username ?? "USERNAME";
|
||||
cipherView.login.password = password ?? "PASSWORD";
|
||||
@ -113,7 +113,7 @@ describe("context-menu", () => {
|
||||
username: "",
|
||||
totp: "",
|
||||
viewPassword: false,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
expect(createSpy).toHaveBeenCalledTimes(1);
|
||||
|
@ -46,7 +46,7 @@ export class MainContextMenuHandler {
|
||||
constructor(
|
||||
private stateService: BrowserStateService,
|
||||
private i18nService: I18nService,
|
||||
private logService: LogService
|
||||
private logService: LogService,
|
||||
) {
|
||||
if (chrome.contextMenus) {
|
||||
this.create = (options) => {
|
||||
@ -89,7 +89,7 @@ export class MainContextMenuHandler {
|
||||
return new MainContextMenuHandler(
|
||||
await stateServiceFactory(cachedServices, serviceOptions),
|
||||
await i18nServiceFactory(cachedServices, serviceOptions),
|
||||
await logServiceFactory(cachedServices, serviceOptions)
|
||||
await logServiceFactory(cachedServices, serviceOptions),
|
||||
);
|
||||
}
|
||||
|
||||
@ -274,7 +274,7 @@ export class MainContextMenuHandler {
|
||||
const authed = await this.stateService.getIsAuthenticated();
|
||||
await this.loadOptions(
|
||||
this.i18nService.t(authed ? "unlockVaultMenu" : "loginToVaultMenu"),
|
||||
NOOP_COMMAND_SUFFIX
|
||||
NOOP_COMMAND_SUFFIX,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import { copyToClipboard } from "./copy-to-clipboard-command";
|
||||
export class GeneratePasswordToClipboardCommand {
|
||||
constructor(
|
||||
private passwordGenerationService: PasswordGenerationServiceAbstraction,
|
||||
private stateService: BrowserStateService
|
||||
private stateService: BrowserStateService,
|
||||
) {}
|
||||
|
||||
async generatePasswordToClipboard(tab: chrome.tabs.Tab) {
|
||||
|
@ -21,7 +21,7 @@ export class AutofillTabCommand {
|
||||
},
|
||||
],
|
||||
tab,
|
||||
true
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ export class AutofillTabCommand {
|
||||
}
|
||||
|
||||
resolve(response);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ describe("AutofillInit", () => {
|
||||
autofillInit["setupExtensionMessageListeners"]();
|
||||
|
||||
expect(chrome.runtime.onMessage.addListener).toHaveBeenCalledWith(
|
||||
autofillInit["handleExtensionMessage"]
|
||||
autofillInit["handleExtensionMessage"],
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -157,7 +157,7 @@ describe("AutofillInit", () => {
|
||||
sendExtensionRuntimeMessage(
|
||||
{ command: "collectPageDetailsImmediately" },
|
||||
sender,
|
||||
sendResponse
|
||||
sendResponse,
|
||||
);
|
||||
await flushPromises();
|
||||
|
||||
@ -186,7 +186,7 @@ describe("AutofillInit", () => {
|
||||
await flushPromises();
|
||||
|
||||
expect(autofillInit["insertAutofillContentService"].fillForm).not.toHaveBeenCalledWith(
|
||||
fillScript
|
||||
fillScript,
|
||||
);
|
||||
});
|
||||
|
||||
@ -199,7 +199,7 @@ describe("AutofillInit", () => {
|
||||
await flushPromises();
|
||||
|
||||
expect(autofillInit["insertAutofillContentService"].fillForm).toHaveBeenCalledWith(
|
||||
fillScript
|
||||
fillScript,
|
||||
);
|
||||
});
|
||||
|
||||
@ -220,11 +220,11 @@ describe("AutofillInit", () => {
|
||||
|
||||
expect(autofillInit["updateOverlayIsCurrentlyFilling"]).toHaveBeenNthCalledWith(1, true);
|
||||
expect(autofillInit["insertAutofillContentService"].fillForm).toHaveBeenCalledWith(
|
||||
fillScript
|
||||
fillScript,
|
||||
);
|
||||
expect(autofillInit["updateOverlayIsCurrentlyFilling"]).toHaveBeenNthCalledWith(2, false);
|
||||
expect(
|
||||
autofillInit["autofillOverlayContentService"].focusMostRecentOverlayField
|
||||
autofillInit["autofillOverlayContentService"].focusMostRecentOverlayField,
|
||||
).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -247,14 +247,14 @@ describe("AutofillInit", () => {
|
||||
|
||||
expect(newAutofillInit["updateOverlayIsCurrentlyFilling"]).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
true
|
||||
true,
|
||||
);
|
||||
expect(newAutofillInit["insertAutofillContentService"].fillForm).toHaveBeenCalledWith(
|
||||
fillScript
|
||||
fillScript,
|
||||
);
|
||||
expect(newAutofillInit["updateOverlayIsCurrentlyFilling"]).not.toHaveBeenNthCalledWith(
|
||||
2,
|
||||
false
|
||||
false,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -282,7 +282,7 @@ describe("AutofillInit", () => {
|
||||
sendExtensionRuntimeMessage(message);
|
||||
|
||||
expect(
|
||||
autofillInit["autofillOverlayContentService"].openAutofillOverlay
|
||||
autofillInit["autofillOverlayContentService"].openAutofillOverlay,
|
||||
).toHaveBeenCalledWith({
|
||||
isFocusingFieldElement: message.data.isFocusingFieldElement,
|
||||
isOpeningFullOverlay: message.data.isOpeningFullOverlay,
|
||||
@ -303,10 +303,10 @@ describe("AutofillInit", () => {
|
||||
sendExtensionRuntimeMessage({ command: "closeAutofillOverlay" });
|
||||
|
||||
expect(
|
||||
autofillInit["autofillOverlayContentService"].removeAutofillOverlayList
|
||||
autofillInit["autofillOverlayContentService"].removeAutofillOverlayList,
|
||||
).not.toHaveBeenCalled();
|
||||
expect(
|
||||
autofillInit["autofillOverlayContentService"].removeAutofillOverlay
|
||||
autofillInit["autofillOverlayContentService"].removeAutofillOverlay,
|
||||
).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -316,10 +316,10 @@ describe("AutofillInit", () => {
|
||||
sendExtensionRuntimeMessage({ command: "closeAutofillOverlay" });
|
||||
|
||||
expect(
|
||||
autofillInit["autofillOverlayContentService"].removeAutofillOverlayList
|
||||
autofillInit["autofillOverlayContentService"].removeAutofillOverlayList,
|
||||
).toHaveBeenCalled();
|
||||
expect(
|
||||
autofillInit["autofillOverlayContentService"].removeAutofillOverlay
|
||||
autofillInit["autofillOverlayContentService"].removeAutofillOverlay,
|
||||
).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -327,10 +327,10 @@ describe("AutofillInit", () => {
|
||||
sendExtensionRuntimeMessage({ command: "closeAutofillOverlay" });
|
||||
|
||||
expect(
|
||||
autofillInit["autofillOverlayContentService"].removeAutofillOverlayList
|
||||
autofillInit["autofillOverlayContentService"].removeAutofillOverlayList,
|
||||
).not.toHaveBeenCalled();
|
||||
expect(
|
||||
autofillInit["autofillOverlayContentService"].removeAutofillOverlay
|
||||
autofillInit["autofillOverlayContentService"].removeAutofillOverlay,
|
||||
).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@ -373,7 +373,7 @@ describe("AutofillInit", () => {
|
||||
sendExtensionRuntimeMessage(message);
|
||||
|
||||
expect(
|
||||
autofillInit["autofillOverlayContentService"].redirectOverlayFocusOut
|
||||
autofillInit["autofillOverlayContentService"].redirectOverlayFocusOut,
|
||||
).toHaveBeenCalledWith(message.data.direction);
|
||||
});
|
||||
});
|
||||
@ -399,7 +399,7 @@ describe("AutofillInit", () => {
|
||||
sendExtensionRuntimeMessage(message);
|
||||
|
||||
expect(autofillInit["autofillOverlayContentService"].isOverlayCiphersPopulated).toEqual(
|
||||
message.data.isOverlayCiphersPopulated
|
||||
message.data.isOverlayCiphersPopulated,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -423,7 +423,7 @@ describe("AutofillInit", () => {
|
||||
sendExtensionRuntimeMessage({ command: "bgUnlockPopoutOpened" });
|
||||
|
||||
expect(
|
||||
autofillInit["autofillOverlayContentService"].blurMostRecentOverlayField
|
||||
autofillInit["autofillOverlayContentService"].blurMostRecentOverlayField,
|
||||
).toHaveBeenCalled();
|
||||
expect(autofillInit["removeAutofillOverlay"]).toHaveBeenCalled();
|
||||
});
|
||||
@ -448,7 +448,7 @@ describe("AutofillInit", () => {
|
||||
sendExtensionRuntimeMessage({ command: "bgVaultItemRepromptPopoutOpened" });
|
||||
|
||||
expect(
|
||||
autofillInit["autofillOverlayContentService"].blurMostRecentOverlayField
|
||||
autofillInit["autofillOverlayContentService"].blurMostRecentOverlayField,
|
||||
).toHaveBeenCalled();
|
||||
expect(autofillInit["removeAutofillOverlay"]).toHaveBeenCalled();
|
||||
});
|
||||
|
@ -39,11 +39,11 @@ class AutofillInit implements AutofillInitInterface {
|
||||
this.domElementVisibilityService = new DomElementVisibilityService();
|
||||
this.collectAutofillContentService = new CollectAutofillContentService(
|
||||
this.domElementVisibilityService,
|
||||
this.autofillOverlayContentService
|
||||
this.autofillOverlayContentService,
|
||||
);
|
||||
this.insertAutofillContentService = new InsertAutofillContentService(
|
||||
this.domElementVisibilityService,
|
||||
this.collectAutofillContentService
|
||||
this.collectAutofillContentService,
|
||||
);
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ class AutofillInit implements AutofillInitInterface {
|
||||
*/
|
||||
private async collectPageDetails(
|
||||
message: AutofillExtensionMessage,
|
||||
sendDetailsInResponse = false
|
||||
sendDetailsInResponse = false,
|
||||
): Promise<AutofillPageDetails | void> {
|
||||
const pageDetails: AutofillPageDetails =
|
||||
await this.collectAutofillContentService.getPageDetails();
|
||||
@ -205,7 +205,7 @@ class AutofillInit implements AutofillInitInterface {
|
||||
}
|
||||
|
||||
this.autofillOverlayContentService.isOverlayCiphersPopulated = Boolean(
|
||||
data?.isOverlayCiphersPopulated
|
||||
data?.isOverlayCiphersPopulated,
|
||||
);
|
||||
}
|
||||
|
||||
@ -226,7 +226,7 @@ class AutofillInit implements AutofillInitInterface {
|
||||
private handleExtensionMessage = (
|
||||
message: AutofillExtensionMessage,
|
||||
sender: chrome.runtime.MessageSender,
|
||||
sendResponse: (response?: any) => void
|
||||
sendResponse: (response?: any) => void,
|
||||
): boolean => {
|
||||
const command: string = message.command;
|
||||
const handler: CallableFunction | undefined = this.extensionMessageHandlers[command];
|
||||
|
@ -24,7 +24,7 @@ window.addEventListener(
|
||||
});
|
||||
}
|
||||
},
|
||||
false
|
||||
false,
|
||||
);
|
||||
|
||||
const forwardCommands = [
|
||||
|
@ -7,7 +7,7 @@ async function copyText(text: string) {
|
||||
async function onMessageListener(
|
||||
msg: TabMessage,
|
||||
sender: chrome.runtime.MessageSender,
|
||||
responseCallback: (response: unknown) => void
|
||||
responseCallback: (response: unknown) => void,
|
||||
) {
|
||||
switch (msg.command) {
|
||||
case "copyText":
|
||||
|
@ -445,7 +445,7 @@ async function loadNotificationBar() {
|
||||
// know what type of form we are watching
|
||||
const submitButton = getSubmitButton(
|
||||
form,
|
||||
unionSets(logInButtonNames, changePasswordButtonNames)
|
||||
unionSets(logInButtonNames, changePasswordButtonNames),
|
||||
);
|
||||
|
||||
if (submitButton != null) {
|
||||
@ -475,7 +475,7 @@ async function loadNotificationBar() {
|
||||
watchedForm.formEl,
|
||||
watchedForm.data.password,
|
||||
inputs,
|
||||
true // Only do fallback if we have expect to find a single password field
|
||||
true, // Only do fallback if we have expect to find a single password field
|
||||
);
|
||||
} else if (watchedForm.data.passwords != null) {
|
||||
// if we didn't find a username field, try to locate multiple password fields
|
||||
@ -499,7 +499,7 @@ async function loadNotificationBar() {
|
||||
form: HTMLFormElement,
|
||||
passwordData: AutofillField,
|
||||
inputs: HTMLInputElement[],
|
||||
doLastFallback: boolean
|
||||
doLastFallback: boolean,
|
||||
): HTMLInputElement {
|
||||
let el = locateField(form, passwordData, inputs);
|
||||
if (el != null && el.type !== "password") {
|
||||
@ -521,7 +521,7 @@ async function loadNotificationBar() {
|
||||
function locateField(
|
||||
form: HTMLFormElement,
|
||||
fieldData: AutofillField,
|
||||
inputs: HTMLInputElement[]
|
||||
inputs: HTMLInputElement[],
|
||||
): HTMLInputElement | null {
|
||||
// If we have no field data, we cannot locate the field
|
||||
if (fieldData == null) {
|
||||
@ -667,7 +667,7 @@ async function loadNotificationBar() {
|
||||
// Check if the submit button contains any of the change password button names as a safeguard
|
||||
const buttonText = getButtonText(getSubmitButton(form, changePasswordButtonNames));
|
||||
const matches = Array.from(changePasswordButtonContainsNames).filter(
|
||||
(n) => buttonText.indexOf(n) > -1
|
||||
(n) => buttonText.indexOf(n) > -1,
|
||||
);
|
||||
|
||||
if (matches.length > 0) {
|
||||
@ -744,8 +744,8 @@ async function loadNotificationBar() {
|
||||
if (submitButton == null) {
|
||||
const possibleSubmitButtons = Array.from(
|
||||
wrappingEl.querySelectorAll(
|
||||
'a, span, button[type="button"], ' + 'input[type="button"], button:not([type])'
|
||||
)
|
||||
'a, span, button[type="button"], ' + 'input[type="button"], button:not([type])',
|
||||
),
|
||||
) as HTMLElement[];
|
||||
let typelessButton: HTMLElement = null;
|
||||
// Loop through all possible submit buttons and find the first one that matches a submit button name
|
||||
|
@ -106,7 +106,7 @@ function createGenerateFillScriptOptionsMock(customFields = {}): GenerateFillScr
|
||||
|
||||
function createAutofillScriptMock(
|
||||
customFields = {},
|
||||
scriptTypes?: Record<string, string>
|
||||
scriptTypes?: Record<string, string>,
|
||||
): AutofillScript {
|
||||
let script: FillScript[] = [
|
||||
["click_on_opid", "default-field"],
|
||||
@ -152,7 +152,7 @@ const overlayPagesTranslations = {
|
||||
addNewVaultItem: "addNewVaultItem",
|
||||
};
|
||||
function createInitAutofillOverlayButtonMessageMock(
|
||||
customFields = {}
|
||||
customFields = {},
|
||||
): InitAutofillOverlayButtonMessage {
|
||||
return {
|
||||
command: "initAutofillOverlayButton",
|
||||
@ -181,7 +181,7 @@ function createAutofillOverlayCipherDataMock(index: number, customFields = {}):
|
||||
}
|
||||
|
||||
function createInitAutofillOverlayListMessageMock(
|
||||
customFields = {}
|
||||
customFields = {},
|
||||
): InitAutofillOverlayListMessage {
|
||||
return {
|
||||
command: "initAutofillOverlayList",
|
||||
|
@ -18,7 +18,7 @@ function postWindowMessage(data: any, origin = "https://localhost/") {
|
||||
function sendExtensionRuntimeMessage(
|
||||
message: any,
|
||||
sender?: chrome.runtime.MessageSender,
|
||||
sendResponse?: CallableFunction
|
||||
sendResponse?: CallableFunction,
|
||||
) {
|
||||
(chrome.runtime.onMessage.addListener as unknown as jest.SpyInstance).mock.calls.forEach(
|
||||
(call) => {
|
||||
@ -26,9 +26,9 @@ function sendExtensionRuntimeMessage(
|
||||
callback(
|
||||
message || {},
|
||||
sender || mock<chrome.runtime.MessageSender>(),
|
||||
sendResponse || jest.fn()
|
||||
sendResponse || jest.fn(),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ function triggerWindowOnFocusedChangedEvent(windowId: number) {
|
||||
(call) => {
|
||||
const callback = call[0];
|
||||
callback(windowId);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ function triggerTabOnActivatedEvent(activeInfo: chrome.tabs.TabActiveInfo) {
|
||||
(call) => {
|
||||
const callback = call[0];
|
||||
callback(activeInfo);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ function triggerTabOnReplacedEvent(addedTabId: number, removedTabId: number) {
|
||||
function triggerTabOnUpdatedEvent(
|
||||
tabId: number,
|
||||
changeInfo: chrome.tabs.TabChangeInfo,
|
||||
tab: chrome.tabs.Tab
|
||||
tab: chrome.tabs.Tab,
|
||||
) {
|
||||
(chrome.tabs.onUpdated.addListener as unknown as jest.SpyInstance).mock.calls.forEach((call) => {
|
||||
const callback = call[0];
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bitwarden</title>
|
||||
|
@ -12,7 +12,7 @@ class AutofillOverlayButtonIframe extends AutofillOverlayIframeElement {
|
||||
border: "none",
|
||||
},
|
||||
chrome.i18n.getMessage("bitwardenOverlayButton"),
|
||||
chrome.i18n.getMessage("bitwardenOverlayMenuAvailable")
|
||||
chrome.i18n.getMessage("bitwardenOverlayMenuAvailable"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ class AutofillOverlayIframeElement extends HTMLElement {
|
||||
portName: string,
|
||||
initStyles: Partial<CSSStyleDeclaration>,
|
||||
iframeTitle: string,
|
||||
ariaAlert?: string
|
||||
ariaAlert?: string,
|
||||
) {
|
||||
super();
|
||||
|
||||
@ -14,7 +14,7 @@ class AutofillOverlayIframeElement extends HTMLElement {
|
||||
const autofillOverlayIframeService = new AutofillOverlayIframeService(
|
||||
iframePath,
|
||||
portName,
|
||||
shadow
|
||||
shadow,
|
||||
);
|
||||
autofillOverlayIframeService.initOverlayIframe(initStyles, iframeTitle, ariaAlert);
|
||||
}
|
||||
|
@ -23,17 +23,17 @@ describe("AutofillOverlayIframeService", () => {
|
||||
autofillOverlayIframeService = new AutofillOverlayIframeService(
|
||||
iframePath,
|
||||
AutofillOverlayPort.Button,
|
||||
shadow
|
||||
shadow,
|
||||
);
|
||||
shadowAppendSpy = jest.spyOn(shadow, "appendChild");
|
||||
handlePortDisconnectSpy = jest.spyOn(
|
||||
autofillOverlayIframeService as any,
|
||||
"handlePortDisconnect"
|
||||
"handlePortDisconnect",
|
||||
);
|
||||
handlePortMessageSpy = jest.spyOn(autofillOverlayIframeService as any, "handlePortMessage");
|
||||
handleWindowMessageSpy = jest.spyOn(autofillOverlayIframeService as any, "handleWindowMessage");
|
||||
chrome.runtime.connect = jest.fn((connectInfo: chrome.runtime.ConnectInfo) =>
|
||||
createPortSpyMock(connectInfo.name)
|
||||
createPortSpyMock(connectInfo.name),
|
||||
) as unknown as typeof chrome.runtime.connect;
|
||||
});
|
||||
|
||||
@ -54,7 +54,7 @@ describe("AutofillOverlayIframeService", () => {
|
||||
autofillOverlayIframeService.initOverlayIframe({}, "title");
|
||||
|
||||
expect(autofillOverlayIframeService["shadow"].appendChild).toBeCalledWith(
|
||||
autofillOverlayIframeService["iframe"]
|
||||
autofillOverlayIframeService["iframe"],
|
||||
);
|
||||
});
|
||||
|
||||
@ -147,7 +147,7 @@ describe("AutofillOverlayIframeService", () => {
|
||||
|
||||
expect(globalThis.removeEventListener).toBeCalledWith(
|
||||
EVENTS.MESSAGE,
|
||||
handleWindowMessageSpy
|
||||
handleWindowMessageSpy,
|
||||
);
|
||||
});
|
||||
|
||||
@ -186,7 +186,7 @@ describe("AutofillOverlayIframeService", () => {
|
||||
|
||||
expect(autofillOverlayIframeService["iframe"].contentWindow.postMessage).toBeCalledWith(
|
||||
message,
|
||||
"*"
|
||||
"*",
|
||||
);
|
||||
});
|
||||
|
||||
@ -204,7 +204,7 @@ describe("AutofillOverlayIframeService", () => {
|
||||
beforeEach(() => {
|
||||
updateElementStylesSpy = jest.spyOn(
|
||||
autofillOverlayIframeService as any,
|
||||
"updateElementStyles"
|
||||
"updateElementStyles",
|
||||
);
|
||||
});
|
||||
|
||||
@ -219,7 +219,7 @@ describe("AutofillOverlayIframeService", () => {
|
||||
expect(updateElementStylesSpy).not.toBeCalled();
|
||||
expect(autofillOverlayIframeService["iframe"].contentWindow.postMessage).toBeCalledWith(
|
||||
message,
|
||||
"*"
|
||||
"*",
|
||||
);
|
||||
});
|
||||
|
||||
@ -344,7 +344,7 @@ describe("AutofillOverlayIframeService", () => {
|
||||
new MessageEvent("message", {
|
||||
data: {},
|
||||
source: window,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
expect(portSpy.postMessage).not.toBeCalled();
|
||||
@ -356,7 +356,7 @@ describe("AutofillOverlayIframeService", () => {
|
||||
data: {},
|
||||
source: autofillOverlayIframeService["iframe"].contentWindow,
|
||||
origin: "https://www.google.com",
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
expect(portSpy.postMessage).not.toBeCalled();
|
||||
@ -368,7 +368,7 @@ describe("AutofillOverlayIframeService", () => {
|
||||
data: { command: "not-a-handled-command" },
|
||||
source: autofillOverlayIframeService["iframe"].contentWindow,
|
||||
origin: "chrome-extension://id",
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
expect(portSpy.postMessage).toBeCalledWith({ command: "not-a-handled-command" });
|
||||
@ -380,7 +380,7 @@ describe("AutofillOverlayIframeService", () => {
|
||||
data: { command: "updateAutofillOverlayListHeight", styles: { height: "300px" } },
|
||||
source: autofillOverlayIframeService["iframe"].contentWindow,
|
||||
origin: "chrome-extension://id",
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
expect(autofillOverlayIframeService["iframe"].style.height).toBe("300px");
|
||||
|
@ -40,7 +40,11 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
|
||||
updateOverlayHidden: ({ message }) => this.updateElementStyles(this.iframe, message.styles),
|
||||
};
|
||||
|
||||
constructor(private iframePath: string, private portName: string, private shadow: ShadowRoot) {
|
||||
constructor(
|
||||
private iframePath: string,
|
||||
private portName: string,
|
||||
private shadow: ShadowRoot,
|
||||
) {
|
||||
this.extensionOriginsSet = new Set([
|
||||
chrome.runtime.getURL("").slice(0, -1).toLowerCase(), // Remove the trailing slash and normalize the extension url to lowercase
|
||||
"null",
|
||||
@ -65,7 +69,7 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
|
||||
initOverlayIframe(
|
||||
initStyles: Partial<CSSStyleDeclaration>,
|
||||
iframeTitle: string,
|
||||
ariaAlert?: string
|
||||
ariaAlert?: string,
|
||||
) {
|
||||
this.iframe = globalThis.document.createElement("iframe");
|
||||
this.iframe.src = chrome.runtime.getURL(this.iframePath);
|
||||
@ -167,7 +171,7 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
|
||||
*/
|
||||
private handlePortMessage = (
|
||||
message: AutofillOverlayIframeExtensionMessage,
|
||||
port: chrome.runtime.Port
|
||||
port: chrome.runtime.Port,
|
||||
) => {
|
||||
if (port.name !== this.portName) {
|
||||
return;
|
||||
|
@ -17,7 +17,7 @@ class AutofillOverlayListIframe extends AutofillOverlayIframeElement {
|
||||
borderStyle: "solid",
|
||||
borderColor: "rgb(206, 212, 220)",
|
||||
},
|
||||
chrome.i18n.getMessage("bitwardenVault")
|
||||
chrome.i18n.getMessage("bitwardenVault"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -25,12 +25,12 @@ describe("AutofillOverlayButton", () => {
|
||||
describe("initAutofillOverlayButton", () => {
|
||||
it("creates the button element with the locked icon when the user's auth status is not Unlocked", () => {
|
||||
postWindowMessage(
|
||||
createInitAutofillOverlayButtonMessageMock({ authStatus: AuthenticationStatus.Locked })
|
||||
createInitAutofillOverlayButtonMessageMock({ authStatus: AuthenticationStatus.Locked }),
|
||||
);
|
||||
|
||||
expect(autofillOverlayButton["buttonElement"]).toMatchSnapshot();
|
||||
expect(autofillOverlayButton["buttonElement"].querySelector("svg")).toBe(
|
||||
autofillOverlayButton["logoLockedIconElement"]
|
||||
autofillOverlayButton["logoLockedIconElement"],
|
||||
);
|
||||
});
|
||||
|
||||
@ -39,7 +39,7 @@ describe("AutofillOverlayButton", () => {
|
||||
|
||||
expect(autofillOverlayButton["buttonElement"]).toMatchSnapshot();
|
||||
expect(autofillOverlayButton["buttonElement"].querySelector("svg")).toBe(
|
||||
autofillOverlayButton["logoIconElement"]
|
||||
autofillOverlayButton["logoIconElement"],
|
||||
);
|
||||
});
|
||||
|
||||
@ -49,7 +49,7 @@ describe("AutofillOverlayButton", () => {
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "overlayButtonClicked" },
|
||||
"https://localhost/"
|
||||
"https://localhost/",
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -74,7 +74,7 @@ describe("AutofillOverlayButton", () => {
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "closeAutofillOverlay" },
|
||||
"https://localhost/"
|
||||
"https://localhost/",
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -58,7 +58,7 @@ class AutofillOverlayButton extends AutofillOverlayPageElement {
|
||||
this.buttonElement.classList.add("overlay-button");
|
||||
this.buttonElement.setAttribute(
|
||||
"aria-label",
|
||||
this.getTranslation("toggleBitwardenVaultOverlay")
|
||||
this.getTranslation("toggleBitwardenVaultOverlay"),
|
||||
);
|
||||
this.buttonElement.addEventListener(EVENTS.CLICK, this.handleButtonElementClick);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bitwarden overlay button</title>
|
||||
|
@ -36,7 +36,7 @@ describe("AutofillOverlayList", () => {
|
||||
createInitAutofillOverlayListMessageMock({
|
||||
authStatus: AuthenticationStatus.Locked,
|
||||
cipherList: [],
|
||||
})
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
@ -52,7 +52,7 @@ describe("AutofillOverlayList", () => {
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "unlockVault" },
|
||||
"https://localhost/"
|
||||
"https://localhost/",
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -63,7 +63,7 @@ describe("AutofillOverlayList", () => {
|
||||
createInitAutofillOverlayListMessageMock({
|
||||
authStatus: AuthenticationStatus.Unlocked,
|
||||
ciphers: [],
|
||||
})
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
@ -79,7 +79,7 @@ describe("AutofillOverlayList", () => {
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "addNewVaultItem" },
|
||||
"https://localhost/"
|
||||
"https://localhost/",
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -113,7 +113,7 @@ describe("AutofillOverlayList", () => {
|
||||
autofillOverlayList["cipherListScrollDebounceTimeout"] = setTimeout(jest.fn, 0);
|
||||
const handleDebouncedScrollEventSpy = jest.spyOn(
|
||||
autofillOverlayList as any,
|
||||
"handleDebouncedScrollEvent"
|
||||
"handleDebouncedScrollEvent",
|
||||
);
|
||||
|
||||
autofillOverlayList["handleCiphersListScrollEvent"]();
|
||||
@ -139,7 +139,7 @@ describe("AutofillOverlayList", () => {
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "fillSelectedListItem", overlayCipherId: "1" },
|
||||
"https://localhost/"
|
||||
"https://localhost/",
|
||||
);
|
||||
});
|
||||
|
||||
@ -227,7 +227,7 @@ describe("AutofillOverlayList", () => {
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "viewSelectedCipher", overlayCipherId: "1" },
|
||||
"https://localhost/"
|
||||
"https://localhost/",
|
||||
);
|
||||
});
|
||||
|
||||
@ -298,7 +298,7 @@ describe("AutofillOverlayList", () => {
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "checkAutofillOverlayButtonFocused" },
|
||||
"https://localhost/"
|
||||
"https://localhost/",
|
||||
);
|
||||
});
|
||||
|
||||
@ -317,7 +317,7 @@ describe("AutofillOverlayList", () => {
|
||||
createInitAutofillOverlayListMessageMock({
|
||||
authStatus: AuthenticationStatus.Locked,
|
||||
cipherList: [],
|
||||
})
|
||||
}),
|
||||
);
|
||||
const unlockButton =
|
||||
autofillOverlayList["overlayListContainer"].querySelector("#unlock-button");
|
||||
@ -382,7 +382,7 @@ describe("AutofillOverlayList", () => {
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "updateAutofillOverlayListHeight", styles: { height: "300px" } },
|
||||
"https://localhost/"
|
||||
"https://localhost/",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -89,7 +89,7 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
|
||||
unlockButtonElement.textContent = this.getTranslation("unlockAccount");
|
||||
unlockButtonElement.setAttribute(
|
||||
"aria-label",
|
||||
`${this.getTranslation("unlockAccount")}, ${this.getTranslation("opensInANewWindow")}`
|
||||
`${this.getTranslation("unlockAccount")}, ${this.getTranslation("opensInANewWindow")}`,
|
||||
);
|
||||
unlockButtonElement.prepend(buildSvgDomElement(lockIcon));
|
||||
unlockButtonElement.addEventListener(EVENTS.CLICK, this.handleUnlockButtonClick);
|
||||
@ -151,7 +151,7 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
|
||||
newItemButton.textContent = this.getTranslation("newItem");
|
||||
newItemButton.setAttribute(
|
||||
"aria-label",
|
||||
`${this.getTranslation("addNewVaultItem")}, ${this.getTranslation("opensInANewWindow")}`
|
||||
`${this.getTranslation("addNewVaultItem")}, ${this.getTranslation("opensInANewWindow")}`,
|
||||
);
|
||||
newItemButton.prepend(buildSvgDomElement(plusIcon));
|
||||
newItemButton.addEventListener(EVENTS.CLICK, this.handeNewItemButtonClick);
|
||||
@ -177,7 +177,7 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
|
||||
private loadPageOfCiphers() {
|
||||
const lastIndex = Math.min(
|
||||
this.currentCipherIndex + this.showCiphersPerPage,
|
||||
this.ciphers.length
|
||||
this.ciphers.length,
|
||||
);
|
||||
for (let cipherIndex = this.currentCipherIndex; cipherIndex < lastIndex; cipherIndex++) {
|
||||
this.ciphersList.appendChild(this.buildOverlayActionsListItem(this.ciphers[cipherIndex]));
|
||||
@ -253,11 +253,11 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
|
||||
fillCipherElement.classList.add("fill-cipher-button");
|
||||
fillCipherElement.setAttribute(
|
||||
"aria-label",
|
||||
`${this.getTranslation("fillCredentialsFor")} ${cipher.name}`
|
||||
`${this.getTranslation("fillCredentialsFor")} ${cipher.name}`,
|
||||
);
|
||||
fillCipherElement.setAttribute(
|
||||
"aria-description",
|
||||
`${this.getTranslation("partialUsername")}, ${cipher.login.username}`
|
||||
`${this.getTranslation("partialUsername")}, ${cipher.login.username}`,
|
||||
);
|
||||
fillCipherElement.append(cipherIcon, cipherDetailsElement);
|
||||
fillCipherElement.addEventListener(EVENTS.CLICK, this.handleFillCipherClickEvent(cipher));
|
||||
@ -279,7 +279,7 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
|
||||
command: "fillSelectedListItem",
|
||||
overlayCipherId: cipher.id,
|
||||
}),
|
||||
`${cipher.id}-fill-cipher-button-click-handler`
|
||||
`${cipher.id}-fill-cipher-button-click-handler`,
|
||||
);
|
||||
};
|
||||
|
||||
@ -323,7 +323,7 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
|
||||
viewCipherElement.classList.add("view-cipher-button");
|
||||
viewCipherElement.setAttribute(
|
||||
"aria-label",
|
||||
`${this.getTranslation("view")} ${cipher.name}, ${this.getTranslation("opensInANewWindow")}`
|
||||
`${this.getTranslation("view")} ${cipher.name}, ${this.getTranslation("opensInANewWindow")}`,
|
||||
);
|
||||
viewCipherElement.append(buildSvgDomElement(viewCipherIcon));
|
||||
viewCipherElement.addEventListener(EVENTS.CLICK, this.handleViewCipherClickEvent(cipher));
|
||||
@ -341,7 +341,7 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
|
||||
private handleViewCipherClickEvent = (cipher: OverlayCipherData) => {
|
||||
return this.useEventHandlersMemo(
|
||||
() => this.postMessageToParent({ command: "viewSelectedCipher", overlayCipherId: cipher.id }),
|
||||
`${cipher.id}-view-cipher-button-click-handler`
|
||||
`${cipher.id}-view-cipher-button-click-handler`,
|
||||
);
|
||||
};
|
||||
|
||||
@ -485,7 +485,7 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
|
||||
*/
|
||||
private focusOverlayList() {
|
||||
const unlockButtonElement = this.overlayListContainer.querySelector(
|
||||
"#unlock-button"
|
||||
"#unlock-button",
|
||||
) as HTMLElement;
|
||||
if (unlockButtonElement) {
|
||||
unlockButtonElement.focus();
|
||||
@ -493,7 +493,7 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
|
||||
}
|
||||
|
||||
const newItemButtonElement = this.overlayListContainer.querySelector(
|
||||
"#new-item-button"
|
||||
"#new-item-button",
|
||||
) as HTMLElement;
|
||||
if (newItemButtonElement) {
|
||||
newItemButtonElement.focus();
|
||||
@ -501,7 +501,7 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
|
||||
}
|
||||
|
||||
const firstCipherElement = this.overlayListContainer.querySelector(
|
||||
".fill-cipher-button"
|
||||
".fill-cipher-button",
|
||||
) as HTMLElement;
|
||||
firstCipherElement?.focus();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bitwarden vault</title>
|
||||
|
@ -35,12 +35,12 @@ describe("AutofillOverlayPageElement", () => {
|
||||
const linkElement = autofillOverlayPageElement["initOverlayPage"](
|
||||
"button",
|
||||
"https://jest-testing-website.com",
|
||||
translations
|
||||
translations,
|
||||
);
|
||||
|
||||
expect(globalThis.document.documentElement.setAttribute).toHaveBeenCalledWith(
|
||||
"lang",
|
||||
translations.locale
|
||||
translations.locale,
|
||||
);
|
||||
expect(globalThis.document.head.title).toEqual(translations.buttonPageTitle);
|
||||
expect(globalThis.document.createElement).toHaveBeenCalledWith("link");
|
||||
@ -62,7 +62,7 @@ describe("AutofillOverlayPageElement", () => {
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "test" },
|
||||
"https://jest-testing-website.com"
|
||||
"https://jest-testing-website.com",
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -79,25 +79,25 @@ describe("AutofillOverlayPageElement", () => {
|
||||
it("sets up global event listeners", () => {
|
||||
const handleWindowMessageSpy = jest.spyOn(
|
||||
autofillOverlayPageElement as any,
|
||||
"handleWindowMessage"
|
||||
"handleWindowMessage",
|
||||
);
|
||||
const handleWindowBlurEventSpy = jest.spyOn(
|
||||
autofillOverlayPageElement as any,
|
||||
"handleWindowBlurEvent"
|
||||
"handleWindowBlurEvent",
|
||||
);
|
||||
const handleDocumentKeyDownEventSpy = jest.spyOn(
|
||||
autofillOverlayPageElement as any,
|
||||
"handleDocumentKeyDownEvent"
|
||||
"handleDocumentKeyDownEvent",
|
||||
);
|
||||
autofillOverlayPageElement["setupGlobalListeners"](
|
||||
mock<OverlayButtonWindowMessageHandlers>()
|
||||
mock<OverlayButtonWindowMessageHandlers>(),
|
||||
);
|
||||
|
||||
expect(globalThis.addEventListener).toHaveBeenCalledWith("message", handleWindowMessageSpy);
|
||||
expect(globalThis.addEventListener).toHaveBeenCalledWith("blur", handleWindowBlurEventSpy);
|
||||
expect(globalThis.document.addEventListener).toHaveBeenCalledWith(
|
||||
"keydown",
|
||||
handleDocumentKeyDownEventSpy
|
||||
handleDocumentKeyDownEventSpy,
|
||||
);
|
||||
});
|
||||
|
||||
@ -106,18 +106,18 @@ describe("AutofillOverlayPageElement", () => {
|
||||
autofillOverlayPageElement["setupGlobalListeners"](
|
||||
mock<OverlayButtonWindowMessageHandlers>({
|
||||
initAutofillOverlayButton: initAutofillOverlayButtonSpy,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
globalThis.dispatchEvent(
|
||||
new MessageEvent("message", {
|
||||
data: { command: "initAutofillOverlayButton" },
|
||||
origin: "https://jest-testing-website.com",
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
expect(autofillOverlayPageElement["messageOrigin"]).toEqual(
|
||||
"https://jest-testing-website.com"
|
||||
"https://jest-testing-website.com",
|
||||
);
|
||||
});
|
||||
|
||||
@ -126,7 +126,7 @@ describe("AutofillOverlayPageElement", () => {
|
||||
autofillOverlayPageElement["setupGlobalListeners"](
|
||||
mock<OverlayButtonWindowMessageHandlers>({
|
||||
initAutofillOverlayButton: initAutofillOverlayButtonSpy,
|
||||
})
|
||||
}),
|
||||
);
|
||||
const data = { command: "initAutofillOverlayButton" };
|
||||
|
||||
@ -140,7 +140,7 @@ describe("AutofillOverlayPageElement", () => {
|
||||
autofillOverlayPageElement["setupGlobalListeners"](
|
||||
mock<OverlayButtonWindowMessageHandlers>({
|
||||
initAutofillOverlayButton: initAutofillOverlayButtonSpy,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
globalThis.dispatchEvent(new MessageEvent("message", { data: { command: "test" } }));
|
||||
@ -151,20 +151,20 @@ describe("AutofillOverlayPageElement", () => {
|
||||
it("posts a message to the parent when the window is blurred", () => {
|
||||
autofillOverlayPageElement["messageOrigin"] = "https://jest-testing-website.com";
|
||||
autofillOverlayPageElement["setupGlobalListeners"](
|
||||
mock<OverlayButtonWindowMessageHandlers>()
|
||||
mock<OverlayButtonWindowMessageHandlers>(),
|
||||
);
|
||||
|
||||
globalThis.dispatchEvent(new Event("blur"));
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "overlayPageBlurred" },
|
||||
"https://jest-testing-website.com"
|
||||
"https://jest-testing-website.com",
|
||||
);
|
||||
});
|
||||
|
||||
it("skips redirecting keyboard focus when a KeyDown event triggers and the key is not a `Tab` or `Escape` key", () => {
|
||||
autofillOverlayPageElement["setupGlobalListeners"](
|
||||
mock<OverlayButtonWindowMessageHandlers>()
|
||||
mock<OverlayButtonWindowMessageHandlers>(),
|
||||
);
|
||||
|
||||
globalThis.document.dispatchEvent(new KeyboardEvent("keydown", { code: "test" }));
|
||||
@ -175,44 +175,44 @@ describe("AutofillOverlayPageElement", () => {
|
||||
it("redirects the overlay focus out to the previous element on KeyDown of the `Tab+Shift` keys", () => {
|
||||
autofillOverlayPageElement["messageOrigin"] = "https://jest-testing-website.com";
|
||||
autofillOverlayPageElement["setupGlobalListeners"](
|
||||
mock<OverlayButtonWindowMessageHandlers>()
|
||||
mock<OverlayButtonWindowMessageHandlers>(),
|
||||
);
|
||||
|
||||
globalThis.document.dispatchEvent(
|
||||
new KeyboardEvent("keydown", { code: "Tab", shiftKey: true })
|
||||
new KeyboardEvent("keydown", { code: "Tab", shiftKey: true }),
|
||||
);
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "redirectOverlayFocusOut", direction: "previous" },
|
||||
"https://jest-testing-website.com"
|
||||
"https://jest-testing-website.com",
|
||||
);
|
||||
});
|
||||
|
||||
it("redirects the overlay focus out to the next element on KeyDown of the `Tab` key", () => {
|
||||
autofillOverlayPageElement["messageOrigin"] = "https://jest-testing-website.com";
|
||||
autofillOverlayPageElement["setupGlobalListeners"](
|
||||
mock<OverlayButtonWindowMessageHandlers>()
|
||||
mock<OverlayButtonWindowMessageHandlers>(),
|
||||
);
|
||||
|
||||
globalThis.document.dispatchEvent(new KeyboardEvent("keydown", { code: "Tab" }));
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "redirectOverlayFocusOut", direction: "next" },
|
||||
"https://jest-testing-website.com"
|
||||
"https://jest-testing-website.com",
|
||||
);
|
||||
});
|
||||
|
||||
it("redirects the overlay focus out to the current element on KeyDown of the `Escape` key", () => {
|
||||
autofillOverlayPageElement["messageOrigin"] = "https://jest-testing-website.com";
|
||||
autofillOverlayPageElement["setupGlobalListeners"](
|
||||
mock<OverlayButtonWindowMessageHandlers>()
|
||||
mock<OverlayButtonWindowMessageHandlers>(),
|
||||
);
|
||||
|
||||
globalThis.document.dispatchEvent(new KeyboardEvent("keydown", { code: "Escape" }));
|
||||
|
||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||
{ command: "redirectOverlayFocusOut", direction: "current" },
|
||||
"https://jest-testing-website.com"
|
||||
"https://jest-testing-website.com",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -28,7 +28,7 @@ class AutofillOverlayPageElement extends HTMLElement {
|
||||
protected initOverlayPage(
|
||||
elementName: "button" | "list",
|
||||
styleSheetUrl: string,
|
||||
translations: Record<string, string>
|
||||
translations: Record<string, string>,
|
||||
): HTMLLinkElement {
|
||||
this.translations = translations;
|
||||
globalThis.document.documentElement.setAttribute("lang", this.getTranslation("locale"));
|
||||
@ -127,7 +127,7 @@ class AutofillOverlayPageElement extends HTMLElement {
|
||||
|
||||
if (event.code === "Tab") {
|
||||
this.redirectOverlayFocusOutMessage(
|
||||
event.shiftKey ? RedirectFocusDirection.Previous : RedirectFocusDirection.Next
|
||||
event.shiftKey ? RedirectFocusDirection.Previous : RedirectFocusDirection.Next,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ interface AutofillOverlayContentService {
|
||||
init(): void;
|
||||
setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement: ElementWithOpId<FormFieldElement>,
|
||||
autofillFieldData: AutofillField
|
||||
autofillFieldData: AutofillField,
|
||||
): Promise<void>;
|
||||
openAutofillOverlay(options: OpenAutofillOverlayOptions): void;
|
||||
removeAutofillOverlay(): void;
|
||||
|
@ -47,19 +47,19 @@ export abstract class AutofillService {
|
||||
injectAutofillScripts: (
|
||||
sender: chrome.runtime.MessageSender,
|
||||
autofillV2?: boolean,
|
||||
autofillOverlay?: boolean
|
||||
autofillOverlay?: boolean,
|
||||
) => Promise<void>;
|
||||
getFormsWithPasswordFields: (pageDetails: AutofillPageDetails) => FormData[];
|
||||
doAutoFill: (options: AutoFillOptions) => Promise<string | null>;
|
||||
doAutoFillOnTab: (
|
||||
pageDetails: PageDetail[],
|
||||
tab: chrome.tabs.Tab,
|
||||
fromCommand: boolean
|
||||
fromCommand: boolean,
|
||||
) => Promise<string | null>;
|
||||
doAutoFillActiveTab: (
|
||||
pageDetails: PageDetail[],
|
||||
fromCommand: boolean,
|
||||
cipherType?: CipherType
|
||||
cipherType?: CipherType,
|
||||
) => Promise<string | null>;
|
||||
isPasswordRepromptRequired: (cipher: CipherView, tab: chrome.tabs.Tab) => Promise<boolean>;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ interface CollectAutofillContentService {
|
||||
queryAllTreeWalkerNodes(
|
||||
rootNode: Node,
|
||||
filterCallback: CallableFunction,
|
||||
isObservingShadowRoot?: boolean
|
||||
isObservingShadowRoot?: boolean,
|
||||
): Node[];
|
||||
}
|
||||
|
||||
|
@ -58,11 +58,11 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest.spyOn(window, "addEventListener");
|
||||
setupGlobalEventListenersSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"setupGlobalEventListeners"
|
||||
"setupGlobalEventListeners",
|
||||
);
|
||||
setupMutationObserverSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"setupMutationObserver"
|
||||
"setupMutationObserver",
|
||||
);
|
||||
});
|
||||
|
||||
@ -76,7 +76,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
expect(document.addEventListener).toHaveBeenCalledWith(
|
||||
"DOMContentLoaded",
|
||||
setupGlobalEventListenersSpy
|
||||
setupGlobalEventListenersSpy,
|
||||
);
|
||||
expect(setupGlobalEventListenersSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
@ -84,21 +84,21 @@ describe("AutofillOverlayContentService", () => {
|
||||
it("sets up a visibility change listener for the DOM", () => {
|
||||
const handleVisibilityChangeEventSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"handleVisibilityChangeEvent"
|
||||
"handleVisibilityChangeEvent",
|
||||
);
|
||||
|
||||
autofillOverlayContentService.init();
|
||||
|
||||
expect(document.addEventListener).toHaveBeenCalledWith(
|
||||
"visibilitychange",
|
||||
handleVisibilityChangeEventSpy
|
||||
handleVisibilityChangeEventSpy,
|
||||
);
|
||||
});
|
||||
|
||||
it("sets up a focus out listener for the window", () => {
|
||||
const handleFormFieldBlurEventSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"handleFormFieldBlurEvent"
|
||||
"handleFormFieldBlurEvent",
|
||||
);
|
||||
|
||||
autofillOverlayContentService.init();
|
||||
@ -112,15 +112,15 @@ describe("AutofillOverlayContentService", () => {
|
||||
.mockImplementation(() => mock<MutationObserver>({ observe: jest.fn() }));
|
||||
const handleOverlayElementMutationObserverUpdateSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"handleOverlayElementMutationObserverUpdate"
|
||||
"handleOverlayElementMutationObserverUpdate",
|
||||
);
|
||||
const handleBodyElementMutationObserverUpdateSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"handleBodyElementMutationObserverUpdate"
|
||||
"handleBodyElementMutationObserverUpdate",
|
||||
);
|
||||
const handleDocumentElementMutationObserverUpdateSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"handleDocumentElementMutationObserverUpdate"
|
||||
"handleDocumentElementMutationObserverUpdate",
|
||||
);
|
||||
|
||||
autofillOverlayContentService.init();
|
||||
@ -128,15 +128,15 @@ describe("AutofillOverlayContentService", () => {
|
||||
expect(setupMutationObserverSpy).toHaveBeenCalledTimes(1);
|
||||
expect(globalThis.MutationObserver).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
handleOverlayElementMutationObserverUpdateSpy
|
||||
handleOverlayElementMutationObserverUpdateSpy,
|
||||
);
|
||||
expect(globalThis.MutationObserver).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
handleBodyElementMutationObserverUpdateSpy
|
||||
handleBodyElementMutationObserverUpdateSpy,
|
||||
);
|
||||
expect(globalThis.MutationObserver).toHaveBeenNthCalledWith(
|
||||
3,
|
||||
handleDocumentElementMutationObserverUpdateSpy
|
||||
handleDocumentElementMutationObserverUpdateSpy,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -154,7 +154,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
`;
|
||||
|
||||
autofillFieldElement = document.getElementById(
|
||||
"username-field"
|
||||
"username-field",
|
||||
) as ElementWithOpId<FormFieldElement>;
|
||||
autofillFieldElement.opid = "op-1";
|
||||
jest.spyOn(autofillFieldElement, "addEventListener");
|
||||
@ -176,7 +176,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
expect(autofillFieldElement.addEventListener).not.toHaveBeenCalled();
|
||||
@ -187,7 +187,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
expect(autofillFieldElement.addEventListener).not.toHaveBeenCalled();
|
||||
@ -198,7 +198,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
expect(autofillFieldElement.addEventListener).not.toHaveBeenCalled();
|
||||
@ -210,7 +210,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
expect(autofillFieldElement.addEventListener).not.toHaveBeenCalled();
|
||||
@ -222,7 +222,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
expect(autofillFieldElement.addEventListener).not.toHaveBeenCalled();
|
||||
@ -233,7 +233,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
expect(autofillFieldElement.addEventListener).not.toHaveBeenCalled();
|
||||
@ -244,7 +244,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
expect(autofillFieldElement.addEventListener).not.toHaveBeenCalled();
|
||||
@ -258,12 +258,12 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("getAutofillOverlayVisibility");
|
||||
expect(autofillOverlayContentService["autofillOverlayVisibility"]).toEqual(
|
||||
AutofillOverlayVisibility.OnFieldFocus
|
||||
AutofillOverlayVisibility.OnFieldFocus,
|
||||
);
|
||||
});
|
||||
|
||||
@ -273,11 +273,11 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
expect(autofillOverlayContentService["autofillOverlayVisibility"]).toEqual(
|
||||
AutofillOverlayVisibility.OnFieldFocus
|
||||
AutofillOverlayVisibility.OnFieldFocus,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -296,23 +296,23 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
expect(autofillFieldElement.removeEventListener).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
"input",
|
||||
inputHandler
|
||||
inputHandler,
|
||||
);
|
||||
expect(autofillFieldElement.removeEventListener).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
"click",
|
||||
clickHandler
|
||||
clickHandler,
|
||||
);
|
||||
expect(autofillFieldElement.removeEventListener).toHaveBeenNthCalledWith(
|
||||
3,
|
||||
"focus",
|
||||
focusHandler
|
||||
focusHandler,
|
||||
);
|
||||
});
|
||||
|
||||
@ -320,7 +320,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
beforeEach(async () => {
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
});
|
||||
|
||||
@ -343,7 +343,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
beforeEach(async () => {
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
jest.spyOn(globalThis.customElements, "define").mockImplementation();
|
||||
});
|
||||
@ -359,7 +359,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
it("repositions the overlay if autofill is not currently filling when the `Enter` key is pressed", () => {
|
||||
const handleOverlayRepositionEventSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"handleOverlayRepositionEvent"
|
||||
"handleOverlayRepositionEvent",
|
||||
);
|
||||
autofillOverlayContentService["isCurrentlyFilling"] = false;
|
||||
|
||||
@ -371,7 +371,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
it("skips repositioning the overlay if autofill is currently filling when the `Enter` key is pressed", () => {
|
||||
const handleOverlayRepositionEventSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"handleOverlayRepositionEvent"
|
||||
"handleOverlayRepositionEvent",
|
||||
);
|
||||
autofillOverlayContentService["isCurrentlyFilling"] = true;
|
||||
|
||||
@ -384,11 +384,11 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest.useFakeTimers();
|
||||
const updateMostRecentlyFocusedFieldSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"updateMostRecentlyFocusedField"
|
||||
"updateMostRecentlyFocusedField",
|
||||
);
|
||||
const openAutofillOverlaySpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"openAutofillOverlay"
|
||||
"openAutofillOverlay",
|
||||
);
|
||||
autofillOverlayContentService["isOverlayListVisible"] = false;
|
||||
|
||||
@ -420,13 +420,13 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
it("ignores span elements that trigger the listener", async () => {
|
||||
const spanAutofillFieldElement = document.createElement(
|
||||
"span"
|
||||
"span",
|
||||
) as ElementWithOpId<HTMLSpanElement>;
|
||||
jest.spyOn(autofillOverlayContentService as any, "storeModifiedFormElement");
|
||||
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
spanAutofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
spanAutofillFieldElement.dispatchEvent(new Event("input"));
|
||||
@ -437,28 +437,28 @@ describe("AutofillOverlayContentService", () => {
|
||||
it("stores the field as a user filled field if the form field data indicates that it is for a username", async () => {
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
autofillFieldElement.dispatchEvent(new Event("input"));
|
||||
|
||||
expect(autofillOverlayContentService["userFilledFields"].username).toEqual(
|
||||
autofillFieldElement
|
||||
autofillFieldElement,
|
||||
);
|
||||
});
|
||||
|
||||
it("stores the field as a user filled field if the form field is of type password", async () => {
|
||||
const passwordFieldElement = document.getElementById(
|
||||
"password-field"
|
||||
"password-field",
|
||||
) as ElementWithOpId<FormFieldElement>;
|
||||
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
passwordFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
passwordFieldElement.dispatchEvent(new Event("input"));
|
||||
|
||||
expect(autofillOverlayContentService["userFilledFields"].password).toEqual(
|
||||
passwordFieldElement
|
||||
passwordFieldElement,
|
||||
);
|
||||
});
|
||||
|
||||
@ -466,13 +466,13 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest.spyOn(autofillOverlayContentService as any, "isUserAuthed").mockReturnValue(false);
|
||||
const removeAutofillOverlayListSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"removeAutofillOverlayList"
|
||||
"removeAutofillOverlayList",
|
||||
);
|
||||
(autofillFieldElement as HTMLInputElement).value = "test";
|
||||
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
autofillFieldElement.dispatchEvent(new Event("input"));
|
||||
|
||||
@ -484,13 +484,13 @@ describe("AutofillOverlayContentService", () => {
|
||||
autofillOverlayContentService["isOverlayCiphersPopulated"] = true;
|
||||
const removeAutofillOverlayListSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"removeAutofillOverlayList"
|
||||
"removeAutofillOverlayList",
|
||||
);
|
||||
(autofillFieldElement as HTMLInputElement).value = "test";
|
||||
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
autofillFieldElement.dispatchEvent(new Event("input"));
|
||||
|
||||
@ -503,7 +503,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
autofillFieldElement.dispatchEvent(new Event("input"));
|
||||
|
||||
@ -517,7 +517,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
autofillFieldElement.dispatchEvent(new Event("input"));
|
||||
|
||||
@ -532,7 +532,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
autofillFieldElement.dispatchEvent(new Event("input"));
|
||||
|
||||
@ -549,7 +549,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
autofillOverlayContentService["isOverlayListVisible"] = false;
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
});
|
||||
|
||||
@ -565,7 +565,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
autofillFieldElement.dispatchEvent(new Event("click"));
|
||||
|
||||
expect(
|
||||
autofillOverlayContentService["triggerFormFieldFocusedAction"]
|
||||
autofillOverlayContentService["triggerFormFieldFocusedAction"],
|
||||
).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -575,7 +575,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
autofillFieldElement.dispatchEvent(new Event("click"));
|
||||
|
||||
expect(
|
||||
autofillOverlayContentService["triggerFormFieldFocusedAction"]
|
||||
autofillOverlayContentService["triggerFormFieldFocusedAction"],
|
||||
).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@ -587,7 +587,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest.spyOn(globalThis.customElements, "define").mockImplementation();
|
||||
updateMostRecentlyFocusedFieldSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"updateMostRecentlyFocusedField"
|
||||
"updateMostRecentlyFocusedField",
|
||||
);
|
||||
autofillOverlayContentService["isCurrentlyFilling"] = false;
|
||||
});
|
||||
@ -599,7 +599,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
AutofillOverlayVisibility.OnFieldFocus;
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
autofillFieldElement.dispatchEvent(new Event("focus"));
|
||||
@ -610,14 +610,14 @@ describe("AutofillOverlayContentService", () => {
|
||||
it("updates the most recently focused field", async () => {
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
autofillFieldElement.dispatchEvent(new Event("focus"));
|
||||
|
||||
expect(updateMostRecentlyFocusedFieldSpy).toHaveBeenCalledWith(autofillFieldElement);
|
||||
expect(autofillOverlayContentService["mostRecentlyFocusedField"]).toEqual(
|
||||
autofillFieldElement
|
||||
autofillFieldElement,
|
||||
);
|
||||
});
|
||||
|
||||
@ -627,7 +627,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
AutofillOverlayVisibility.OnButtonClick;
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
autofillFieldElement.dispatchEvent(new Event("focus"));
|
||||
@ -641,12 +641,12 @@ describe("AutofillOverlayContentService", () => {
|
||||
it("removes the overlay list if the form element has a value and the focused field is newly focused", async () => {
|
||||
autofillOverlayContentService["overlayListElement"] = document.createElement("div");
|
||||
autofillOverlayContentService["mostRecentlyFocusedField"] = document.createElement(
|
||||
"input"
|
||||
"input",
|
||||
) as ElementWithOpId<HTMLInputElement>;
|
||||
(autofillFieldElement as HTMLInputElement).value = "test";
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
autofillFieldElement.dispatchEvent(new Event("focus"));
|
||||
@ -664,7 +664,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
AutofillOverlayVisibility.OnFieldFocus;
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
autofillFieldElement.dispatchEvent(new Event("focus"));
|
||||
@ -681,7 +681,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest.spyOn(autofillOverlayContentService as any, "isUserAuthed").mockReturnValue(true);
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
autofillFieldElement.dispatchEvent(new Event("focus"));
|
||||
@ -697,7 +697,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
autofillOverlayContentService["isOverlayCiphersPopulated"] = true;
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
autofillFieldElement.dispatchEvent(new Event("focus"));
|
||||
@ -719,12 +719,12 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("openAutofillOverlay");
|
||||
expect(autofillOverlayContentService["mostRecentlyFocusedField"]).toEqual(
|
||||
autofillFieldElement
|
||||
autofillFieldElement,
|
||||
);
|
||||
});
|
||||
|
||||
@ -733,11 +733,11 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
await autofillOverlayContentService.setupAutofillOverlayListenerOnField(
|
||||
autofillFieldElement,
|
||||
autofillFieldData
|
||||
autofillFieldData,
|
||||
);
|
||||
|
||||
expect(autofillOverlayContentService["mostRecentlyFocusedField"]).toEqual(
|
||||
autofillFieldElement
|
||||
autofillFieldElement,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -754,7 +754,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
`;
|
||||
|
||||
autofillFieldElement = document.getElementById(
|
||||
"username-field"
|
||||
"username-field",
|
||||
) as ElementWithOpId<FormFieldElement>;
|
||||
autofillFieldElement.opid = "op-1";
|
||||
autofillOverlayContentService["mostRecentlyFocusedField"] = autofillFieldElement;
|
||||
@ -776,7 +776,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
});
|
||||
const focusMostRecentOverlayFieldSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"focusMostRecentOverlayField"
|
||||
"focusMostRecentOverlayField",
|
||||
);
|
||||
|
||||
autofillOverlayContentService["openAutofillOverlay"]({ isFocusingFieldElement: true });
|
||||
@ -792,7 +792,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
});
|
||||
const focusMostRecentOverlayFieldSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"focusMostRecentOverlayField"
|
||||
"focusMostRecentOverlayField",
|
||||
);
|
||||
|
||||
autofillOverlayContentService["openAutofillOverlay"]({ isFocusingFieldElement: true });
|
||||
@ -866,7 +866,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
describe("focusMostRecentOverlayField", () => {
|
||||
it("focuses the most recently focused overlay field", () => {
|
||||
const mostRecentlyFocusedField = document.createElement(
|
||||
"input"
|
||||
"input",
|
||||
) as ElementWithOpId<HTMLInputElement>;
|
||||
autofillOverlayContentService["mostRecentlyFocusedField"] = mostRecentlyFocusedField;
|
||||
jest.spyOn(mostRecentlyFocusedField, "focus");
|
||||
@ -880,7 +880,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
describe("blurMostRecentOverlayField", () => {
|
||||
it("removes focus from the most recently focused overlay field", () => {
|
||||
const mostRecentlyFocusedField = document.createElement(
|
||||
"input"
|
||||
"input",
|
||||
) as ElementWithOpId<HTMLInputElement>;
|
||||
autofillOverlayContentService["mostRecentlyFocusedField"] = mostRecentlyFocusedField;
|
||||
jest.spyOn(mostRecentlyFocusedField, "blur");
|
||||
@ -906,7 +906,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = `<div class="overlay-button"></div>`;
|
||||
autofillOverlayContentService["overlayButtonElement"] = document.querySelector(
|
||||
".overlay-button"
|
||||
".overlay-button",
|
||||
) as HTMLElement;
|
||||
});
|
||||
|
||||
@ -933,7 +933,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest.spyOn(globalThis, "removeEventListener");
|
||||
const handleOverlayRepositionEventSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"handleOverlayRepositionEvent"
|
||||
"handleOverlayRepositionEvent",
|
||||
);
|
||||
|
||||
autofillOverlayContentService.removeAutofillOverlay();
|
||||
@ -943,11 +943,11 @@ describe("AutofillOverlayContentService", () => {
|
||||
handleOverlayRepositionEventSpy,
|
||||
{
|
||||
capture: true,
|
||||
}
|
||||
},
|
||||
);
|
||||
expect(globalThis.removeEventListener).toHaveBeenCalledWith(
|
||||
EVENTS.RESIZE,
|
||||
handleOverlayRepositionEventSpy
|
||||
handleOverlayRepositionEventSpy,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -956,7 +956,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = `<div class="overlay-list"></div>`;
|
||||
autofillOverlayContentService["overlayListElement"] = document.querySelector(
|
||||
".overlay-list"
|
||||
".overlay-list",
|
||||
) as HTMLElement;
|
||||
});
|
||||
|
||||
@ -1011,10 +1011,10 @@ describe("AutofillOverlayContentService", () => {
|
||||
</form>
|
||||
`;
|
||||
const usernameField = document.getElementById(
|
||||
"username-field"
|
||||
"username-field",
|
||||
) as ElementWithOpId<HTMLInputElement>;
|
||||
const passwordField = document.getElementById(
|
||||
"password-field"
|
||||
"password-field",
|
||||
) as ElementWithOpId<HTMLInputElement>;
|
||||
usernameField.value = "test-username";
|
||||
passwordField.value = "test-password";
|
||||
@ -1054,11 +1054,11 @@ describe("AutofillOverlayContentService", () => {
|
||||
<div class="next-focusable-element" tabindex="0"></div>
|
||||
`;
|
||||
autofillFieldElement = document.getElementById(
|
||||
"username-field"
|
||||
"username-field",
|
||||
) as ElementWithOpId<FormFieldElement>;
|
||||
autofillFieldElement.opid = "op-1";
|
||||
previousFocusableElement = document.querySelector(
|
||||
".previous-focusable-element"
|
||||
".previous-focusable-element",
|
||||
) as HTMLElement;
|
||||
nextFocusableElement = document.querySelector(".next-focusable-element") as HTMLElement;
|
||||
autofillFieldFocusSpy = jest.spyOn(autofillFieldElement, "focus");
|
||||
@ -1099,7 +1099,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest.useFakeTimers();
|
||||
const removeAutofillOverlaySpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"removeAutofillOverlay"
|
||||
"removeAutofillOverlay",
|
||||
);
|
||||
|
||||
autofillOverlayContentService.redirectOverlayFocusOut(RedirectFocusDirection.Current);
|
||||
@ -1149,7 +1149,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
</form>
|
||||
`;
|
||||
const usernameField = document.getElementById(
|
||||
"username-field"
|
||||
"username-field",
|
||||
) as ElementWithOpId<HTMLInputElement>;
|
||||
autofillOverlayContentService["mostRecentlyFocusedField"] = usernameField;
|
||||
autofillOverlayContentService["setOverlayRepositionEventListeners"]();
|
||||
@ -1196,7 +1196,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
.mockReturnValue(false);
|
||||
const removeAutofillOverlaySpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"removeAutofillOverlay"
|
||||
"removeAutofillOverlay",
|
||||
);
|
||||
autofillOverlayContentService["mostRecentlyFocusedField"] = undefined;
|
||||
|
||||
@ -1225,7 +1225,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
});
|
||||
const clearUserInteractionEventTimeoutSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"clearUserInteractionEventTimeout"
|
||||
"clearUserInteractionEventTimeout",
|
||||
);
|
||||
|
||||
globalThis.dispatchEvent(new Event(EVENTS.SCROLL));
|
||||
@ -1255,7 +1255,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
});
|
||||
const removeAutofillOverlaySpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"removeAutofillOverlay"
|
||||
"removeAutofillOverlay",
|
||||
);
|
||||
|
||||
globalThis.dispatchEvent(new Event(EVENTS.SCROLL));
|
||||
@ -1277,7 +1277,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
</form>
|
||||
`;
|
||||
usernameField = document.getElementById(
|
||||
"username-field"
|
||||
"username-field",
|
||||
) as ElementWithOpId<HTMLInputElement>;
|
||||
usernameField.style.setProperty("display", "block", "important");
|
||||
jest.spyOn(usernameField, "removeAttribute");
|
||||
@ -1285,7 +1285,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest
|
||||
.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"isTriggeringExcessiveMutationObserverIterations"
|
||||
"isTriggeringExcessiveMutationObserverIterations",
|
||||
)
|
||||
.mockReturnValue(false);
|
||||
});
|
||||
@ -1294,7 +1294,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest
|
||||
.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"isTriggeringExcessiveMutationObserverIterations"
|
||||
"isTriggeringExcessiveMutationObserverIterations",
|
||||
)
|
||||
.mockReturnValue(true);
|
||||
|
||||
@ -1344,7 +1344,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
expect(usernameField.style.setProperty).toHaveBeenCalledWith(
|
||||
"position",
|
||||
"fixed",
|
||||
"important"
|
||||
"important",
|
||||
);
|
||||
expect(usernameField.style.setProperty).toHaveBeenCalledWith("display", "block", "important");
|
||||
});
|
||||
@ -1368,7 +1368,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest
|
||||
.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"isTriggeringExcessiveMutationObserverIterations"
|
||||
"isTriggeringExcessiveMutationObserverIterations",
|
||||
)
|
||||
.mockReturnValue(false);
|
||||
});
|
||||
@ -1386,7 +1386,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest
|
||||
.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"isTriggeringExcessiveMutationObserverIterations"
|
||||
"isTriggeringExcessiveMutationObserverIterations",
|
||||
)
|
||||
.mockReturnValue(true);
|
||||
|
||||
@ -1418,7 +1418,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
expect(globalThis.document.body.insertBefore).toHaveBeenCalledWith(
|
||||
overlayButtonElement,
|
||||
overlayListElement
|
||||
overlayListElement,
|
||||
);
|
||||
});
|
||||
|
||||
@ -1429,7 +1429,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
expect(globalThis.document.body.insertBefore).toHaveBeenCalledWith(
|
||||
overlayButtonElement,
|
||||
overlayListElement
|
||||
overlayListElement,
|
||||
);
|
||||
});
|
||||
|
||||
@ -1441,7 +1441,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
|
||||
expect(globalThis.document.body.insertBefore).toHaveBeenCalledWith(
|
||||
injectedElement,
|
||||
overlayButtonElement
|
||||
overlayButtonElement,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1465,7 +1465,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest
|
||||
.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"isTriggeringExcessiveMutationObserverIterations"
|
||||
"isTriggeringExcessiveMutationObserverIterations",
|
||||
)
|
||||
.mockReturnValue(false);
|
||||
});
|
||||
@ -1485,7 +1485,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
jest
|
||||
.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"isTriggeringExcessiveMutationObserverIterations"
|
||||
"isTriggeringExcessiveMutationObserverIterations",
|
||||
)
|
||||
.mockReturnValue(true);
|
||||
|
||||
@ -1551,7 +1551,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
const clearTimeoutSpy = jest.spyOn(globalThis, "clearTimeout");
|
||||
autofillOverlayContentService["mutationObserverIterationsResetTimeout"] = setTimeout(
|
||||
jest.fn(),
|
||||
123
|
||||
123,
|
||||
);
|
||||
|
||||
autofillOverlayContentService["isTriggeringExcessiveMutationObserverIterations"]();
|
||||
@ -1573,11 +1573,11 @@ describe("AutofillOverlayContentService", () => {
|
||||
autofillOverlayContentService["mutationObserverIterations"] = 101;
|
||||
const blurMostRecentOverlayFieldSpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"blurMostRecentOverlayField"
|
||||
"blurMostRecentOverlayField",
|
||||
);
|
||||
const removeAutofillOverlaySpy = jest.spyOn(
|
||||
autofillOverlayContentService as any,
|
||||
"removeAutofillOverlay"
|
||||
"removeAutofillOverlay",
|
||||
);
|
||||
|
||||
autofillOverlayContentService["isTriggeringExcessiveMutationObserverIterations"]();
|
||||
|
@ -80,7 +80,7 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
*/
|
||||
async setupAutofillOverlayListenerOnField(
|
||||
formFieldElement: ElementWithOpId<FormFieldElement>,
|
||||
autofillFieldData: AutofillField
|
||||
autofillFieldData: AutofillField,
|
||||
) {
|
||||
if (this.isIgnoredField(autofillFieldData)) {
|
||||
return;
|
||||
@ -241,7 +241,7 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
}
|
||||
|
||||
const focusedElementIndex = this.focusableElements.findIndex(
|
||||
(element) => element === this.mostRecentlyFocusedField
|
||||
(element) => element === this.mostRecentlyFocusedField,
|
||||
);
|
||||
|
||||
const indexOffset = direction === RedirectFocusDirection.Previous ? -1 : 1;
|
||||
@ -263,15 +263,15 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
formFieldElement.addEventListener(EVENTS.KEYUP, this.handleFormFieldKeyupEvent);
|
||||
formFieldElement.addEventListener(
|
||||
EVENTS.INPUT,
|
||||
this.handleFormFieldInputEvent(formFieldElement)
|
||||
this.handleFormFieldInputEvent(formFieldElement),
|
||||
);
|
||||
formFieldElement.addEventListener(
|
||||
EVENTS.CLICK,
|
||||
this.handleFormFieldClickEvent(formFieldElement)
|
||||
this.handleFormFieldClickEvent(formFieldElement),
|
||||
);
|
||||
formFieldElement.addEventListener(
|
||||
EVENTS.FOCUS,
|
||||
this.handleFormFieldFocusEvent(formFieldElement)
|
||||
this.handleFormFieldFocusEvent(formFieldElement),
|
||||
);
|
||||
}
|
||||
|
||||
@ -314,7 +314,7 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
*/
|
||||
private getFormFieldHandlerMemoIndex(
|
||||
formFieldElement: ElementWithOpId<FormFieldElement>,
|
||||
event: string
|
||||
event: string,
|
||||
) {
|
||||
return `${formFieldElement.opid}-${formFieldElement.id}-${event}-handler`;
|
||||
}
|
||||
@ -381,7 +381,7 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
private handleFormFieldInputEvent = (formFieldElement: ElementWithOpId<FormFieldElement>) => {
|
||||
return this.useEventHandlersMemo(
|
||||
() => this.triggerFormFieldInput(formFieldElement),
|
||||
this.getFormFieldHandlerMemoIndex(formFieldElement, EVENTS.INPUT)
|
||||
this.getFormFieldHandlerMemoIndex(formFieldElement, EVENTS.INPUT),
|
||||
);
|
||||
};
|
||||
|
||||
@ -436,7 +436,7 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
private handleFormFieldClickEvent = (formFieldElement: ElementWithOpId<FormFieldElement>) => {
|
||||
return this.useEventHandlersMemo(
|
||||
() => this.triggerFormFieldClickedAction(formFieldElement),
|
||||
this.getFormFieldHandlerMemoIndex(formFieldElement, EVENTS.CLICK)
|
||||
this.getFormFieldHandlerMemoIndex(formFieldElement, EVENTS.CLICK),
|
||||
);
|
||||
};
|
||||
|
||||
@ -462,7 +462,7 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
private handleFormFieldFocusEvent = (formFieldElement: ElementWithOpId<FormFieldElement>) => {
|
||||
return this.useEventHandlersMemo(
|
||||
() => this.triggerFormFieldFocusedAction(formFieldElement),
|
||||
this.getFormFieldHandlerMemoIndex(formFieldElement, EVENTS.FOCUS)
|
||||
this.getFormFieldHandlerMemoIndex(formFieldElement, EVENTS.FOCUS),
|
||||
);
|
||||
};
|
||||
|
||||
@ -637,13 +637,12 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
* @param formFieldElement - The form field element that triggered the focus event.
|
||||
*/
|
||||
private async updateMostRecentlyFocusedField(
|
||||
formFieldElement: ElementWithOpId<FormFieldElement>
|
||||
formFieldElement: ElementWithOpId<FormFieldElement>,
|
||||
) {
|
||||
this.mostRecentlyFocusedField = formFieldElement;
|
||||
const { paddingRight, paddingLeft } = globalThis.getComputedStyle(formFieldElement);
|
||||
const { width, height, top, left } = await this.getMostRecentlyFocusedFieldRects(
|
||||
formFieldElement
|
||||
);
|
||||
const { width, height, top, left } =
|
||||
await this.getMostRecentlyFocusedFieldRects(formFieldElement);
|
||||
this.focusedFieldData = {
|
||||
focusedFieldStyles: { paddingRight, paddingLeft },
|
||||
focusedFieldRects: { width, height, top, left },
|
||||
@ -664,11 +663,10 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
* @param formFieldElement - The form field element that triggered the focus event.
|
||||
*/
|
||||
private async getMostRecentlyFocusedFieldRects(
|
||||
formFieldElement: ElementWithOpId<FormFieldElement>
|
||||
formFieldElement: ElementWithOpId<FormFieldElement>,
|
||||
) {
|
||||
const focusedFieldRects = await this.getBoundingClientRectFromIntersectionObserver(
|
||||
formFieldElement
|
||||
);
|
||||
const focusedFieldRects =
|
||||
await this.getBoundingClientRectFromIntersectionObserver(formFieldElement);
|
||||
if (focusedFieldRects) {
|
||||
return focusedFieldRects;
|
||||
}
|
||||
@ -682,7 +680,7 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
* @param formFieldElement - The form field element that triggered the focus event.
|
||||
*/
|
||||
private async getBoundingClientRectFromIntersectionObserver(
|
||||
formFieldElement: ElementWithOpId<FormFieldElement>
|
||||
formFieldElement: ElementWithOpId<FormFieldElement>,
|
||||
): Promise<DOMRectReadOnly | null> {
|
||||
if (!("IntersectionObserver" in window) && !("IntersectionObserverEntry" in window)) {
|
||||
return null;
|
||||
@ -703,7 +701,7 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
root: globalThis.document.body,
|
||||
rootMargin: "0px",
|
||||
threshold: 0.9999, // Safari doesn't seem to function properly with a threshold of 1
|
||||
}
|
||||
},
|
||||
);
|
||||
intersectionObserver.observe(formFieldElement);
|
||||
});
|
||||
@ -896,15 +894,15 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
*/
|
||||
private setupMutationObserver = () => {
|
||||
this.overlayElementsMutationObserver = new MutationObserver(
|
||||
this.handleOverlayElementMutationObserverUpdate
|
||||
this.handleOverlayElementMutationObserverUpdate,
|
||||
);
|
||||
|
||||
this.bodyElementMutationObserver = new MutationObserver(
|
||||
this.handleBodyElementMutationObserverUpdate
|
||||
this.handleBodyElementMutationObserverUpdate,
|
||||
);
|
||||
|
||||
const documentElementMutationObserver = new MutationObserver(
|
||||
this.handleDocumentElementMutationObserverUpdate
|
||||
this.handleDocumentElementMutationObserverUpdate,
|
||||
);
|
||||
documentElementMutationObserver.observe(globalThis.document.documentElement, {
|
||||
childList: true,
|
||||
@ -1095,7 +1093,7 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
this.mutationObserverIterations++;
|
||||
this.mutationObserverIterationsResetTimeout = setTimeout(
|
||||
() => (this.mutationObserverIterations = 0),
|
||||
2000
|
||||
2000,
|
||||
);
|
||||
|
||||
if (this.mutationObserverIterations > 100) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -43,7 +43,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
private eventCollectionService: EventCollectionService,
|
||||
private logService: LogService,
|
||||
private settingsService: SettingsService,
|
||||
private userVerificationService: UserVerificationService
|
||||
private userVerificationService: UserVerificationService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@ -59,7 +59,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
async injectAutofillScripts(
|
||||
sender: chrome.runtime.MessageSender,
|
||||
autofillV2 = false,
|
||||
autofillOverlay = false
|
||||
autofillOverlay = false,
|
||||
) {
|
||||
let mainAutofillScript = "autofill.js";
|
||||
|
||||
@ -226,7 +226,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
url: tab.url,
|
||||
pageDetailsUrl: pd.details.url,
|
||||
},
|
||||
{ frameId: pd.frameId }
|
||||
{ frameId: pd.frameId },
|
||||
);
|
||||
|
||||
// Skip getting the TOTP code for clipboard in these cases
|
||||
@ -245,7 +245,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
}
|
||||
return null;
|
||||
});
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
if (didAutofill) {
|
||||
@ -270,7 +270,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
async doAutoFillOnTab(
|
||||
pageDetails: PageDetail[],
|
||||
tab: chrome.tabs.Tab,
|
||||
fromCommand: boolean
|
||||
fromCommand: boolean,
|
||||
): Promise<string | null> {
|
||||
let cipher: CipherView;
|
||||
if (fromCommand) {
|
||||
@ -347,7 +347,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
async doAutoFillActiveTab(
|
||||
pageDetails: PageDetail[],
|
||||
fromCommand: boolean,
|
||||
cipherType?: CipherType
|
||||
cipherType?: CipherType,
|
||||
): Promise<string | null> {
|
||||
if (!pageDetails[0]?.details?.fields?.length) {
|
||||
return null;
|
||||
@ -410,7 +410,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
*/
|
||||
private async generateFillScript(
|
||||
pageDetails: AutofillPageDetails,
|
||||
options: GenerateFillScriptOptions
|
||||
options: GenerateFillScriptOptions,
|
||||
): Promise<AutofillScript | null> {
|
||||
if (!pageDetails || !options.cipher) {
|
||||
return null;
|
||||
@ -465,7 +465,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillScript,
|
||||
pageDetails,
|
||||
filledFields,
|
||||
options
|
||||
options,
|
||||
);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
@ -476,7 +476,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillScript,
|
||||
pageDetails,
|
||||
filledFields,
|
||||
options
|
||||
options,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
@ -499,7 +499,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillScript: AutofillScript,
|
||||
pageDetails: AutofillPageDetails,
|
||||
filledFields: { [id: string]: AutofillField },
|
||||
options: GenerateFillScriptOptions
|
||||
options: GenerateFillScriptOptions,
|
||||
): Promise<AutofillScript | null> {
|
||||
if (!options.cipher.login) {
|
||||
return null;
|
||||
@ -522,7 +522,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
false,
|
||||
false,
|
||||
options.onlyEmptyFields,
|
||||
options.fillNewPassword
|
||||
options.fillNewPassword,
|
||||
);
|
||||
if (!passwordFields.length && !options.onlyVisibleFields) {
|
||||
// not able to find any viewable password fields. maybe there are some "hidden" ones?
|
||||
@ -531,7 +531,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
true,
|
||||
true,
|
||||
options.onlyEmptyFields,
|
||||
options.fillNewPassword
|
||||
options.fillNewPassword,
|
||||
);
|
||||
}
|
||||
|
||||
@ -661,7 +661,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
filledFields[t.opid] = t;
|
||||
const totpValue = await this.totpService.getCode(login.totp);
|
||||
AutofillService.fillByOpid(fillScript, t, totpValue);
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@ -682,7 +682,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillScript: AutofillScript,
|
||||
pageDetails: AutofillPageDetails,
|
||||
filledFields: { [id: string]: AutofillField },
|
||||
options: GenerateFillScriptOptions
|
||||
options: GenerateFillScriptOptions,
|
||||
): AutofillScript | null {
|
||||
if (!options.cipher.card) {
|
||||
return null;
|
||||
@ -713,7 +713,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
AutofillService.isFieldMatch(
|
||||
f[attr],
|
||||
CreditCardAutoFillConstants.CardHolderFieldNames,
|
||||
CreditCardAutoFillConstants.CardHolderFieldNameValues
|
||||
CreditCardAutoFillConstants.CardHolderFieldNameValues,
|
||||
)
|
||||
) {
|
||||
fillFields.cardholderName = f;
|
||||
@ -723,7 +723,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
AutofillService.isFieldMatch(
|
||||
f[attr],
|
||||
CreditCardAutoFillConstants.CardNumberFieldNames,
|
||||
CreditCardAutoFillConstants.CardNumberFieldNameValues
|
||||
CreditCardAutoFillConstants.CardNumberFieldNameValues,
|
||||
)
|
||||
) {
|
||||
fillFields.number = f;
|
||||
@ -733,7 +733,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
AutofillService.isFieldMatch(
|
||||
f[attr],
|
||||
CreditCardAutoFillConstants.CardExpiryFieldNames,
|
||||
CreditCardAutoFillConstants.CardExpiryFieldNameValues
|
||||
CreditCardAutoFillConstants.CardExpiryFieldNameValues,
|
||||
)
|
||||
) {
|
||||
fillFields.exp = f;
|
||||
@ -879,7 +879,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillFields.exp,
|
||||
CreditCardAutoFillConstants.MonthAbbr[i] +
|
||||
"/" +
|
||||
CreditCardAutoFillConstants.YearAbbrLong[i]
|
||||
CreditCardAutoFillConstants.YearAbbrLong[i],
|
||||
)
|
||||
) {
|
||||
exp = fullMonth + "/" + fullYear;
|
||||
@ -888,7 +888,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillFields.exp,
|
||||
CreditCardAutoFillConstants.MonthAbbr[i] +
|
||||
"/" +
|
||||
CreditCardAutoFillConstants.YearAbbrShort[i]
|
||||
CreditCardAutoFillConstants.YearAbbrShort[i],
|
||||
) &&
|
||||
partYear != null
|
||||
) {
|
||||
@ -898,7 +898,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillFields.exp,
|
||||
CreditCardAutoFillConstants.YearAbbrLong[i] +
|
||||
"/" +
|
||||
CreditCardAutoFillConstants.MonthAbbr[i]
|
||||
CreditCardAutoFillConstants.MonthAbbr[i],
|
||||
)
|
||||
) {
|
||||
exp = fullYear + "/" + fullMonth;
|
||||
@ -907,7 +907,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillFields.exp,
|
||||
CreditCardAutoFillConstants.YearAbbrShort[i] +
|
||||
"/" +
|
||||
CreditCardAutoFillConstants.MonthAbbr[i]
|
||||
CreditCardAutoFillConstants.MonthAbbr[i],
|
||||
) &&
|
||||
partYear != null
|
||||
) {
|
||||
@ -917,7 +917,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillFields.exp,
|
||||
CreditCardAutoFillConstants.MonthAbbr[i] +
|
||||
"-" +
|
||||
CreditCardAutoFillConstants.YearAbbrLong[i]
|
||||
CreditCardAutoFillConstants.YearAbbrLong[i],
|
||||
)
|
||||
) {
|
||||
exp = fullMonth + "-" + fullYear;
|
||||
@ -926,7 +926,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillFields.exp,
|
||||
CreditCardAutoFillConstants.MonthAbbr[i] +
|
||||
"-" +
|
||||
CreditCardAutoFillConstants.YearAbbrShort[i]
|
||||
CreditCardAutoFillConstants.YearAbbrShort[i],
|
||||
) &&
|
||||
partYear != null
|
||||
) {
|
||||
@ -936,7 +936,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillFields.exp,
|
||||
CreditCardAutoFillConstants.YearAbbrLong[i] +
|
||||
"-" +
|
||||
CreditCardAutoFillConstants.MonthAbbr[i]
|
||||
CreditCardAutoFillConstants.MonthAbbr[i],
|
||||
)
|
||||
) {
|
||||
exp = fullYear + "-" + fullMonth;
|
||||
@ -945,7 +945,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillFields.exp,
|
||||
CreditCardAutoFillConstants.YearAbbrShort[i] +
|
||||
"-" +
|
||||
CreditCardAutoFillConstants.MonthAbbr[i]
|
||||
CreditCardAutoFillConstants.MonthAbbr[i],
|
||||
) &&
|
||||
partYear != null
|
||||
) {
|
||||
@ -953,14 +953,14 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
} else if (
|
||||
this.fieldAttrsContain(
|
||||
fillFields.exp,
|
||||
CreditCardAutoFillConstants.YearAbbrLong[i] + CreditCardAutoFillConstants.MonthAbbr[i]
|
||||
CreditCardAutoFillConstants.YearAbbrLong[i] + CreditCardAutoFillConstants.MonthAbbr[i],
|
||||
)
|
||||
) {
|
||||
exp = fullYear + fullMonth;
|
||||
} else if (
|
||||
this.fieldAttrsContain(
|
||||
fillFields.exp,
|
||||
CreditCardAutoFillConstants.YearAbbrShort[i] + CreditCardAutoFillConstants.MonthAbbr[i]
|
||||
CreditCardAutoFillConstants.YearAbbrShort[i] + CreditCardAutoFillConstants.MonthAbbr[i],
|
||||
) &&
|
||||
partYear != null
|
||||
) {
|
||||
@ -968,14 +968,14 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
} else if (
|
||||
this.fieldAttrsContain(
|
||||
fillFields.exp,
|
||||
CreditCardAutoFillConstants.MonthAbbr[i] + CreditCardAutoFillConstants.YearAbbrLong[i]
|
||||
CreditCardAutoFillConstants.MonthAbbr[i] + CreditCardAutoFillConstants.YearAbbrLong[i],
|
||||
)
|
||||
) {
|
||||
exp = fullMonth + fullYear;
|
||||
} else if (
|
||||
this.fieldAttrsContain(
|
||||
fillFields.exp,
|
||||
CreditCardAutoFillConstants.MonthAbbr[i] + CreditCardAutoFillConstants.YearAbbrShort[i]
|
||||
CreditCardAutoFillConstants.MonthAbbr[i] + CreditCardAutoFillConstants.YearAbbrShort[i],
|
||||
) &&
|
||||
partYear != null
|
||||
) {
|
||||
@ -1018,7 +1018,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
const matchesUri = options.cipher.login.matchesUri(
|
||||
pageUrl,
|
||||
equivalentDomains,
|
||||
options.defaultUriMatch
|
||||
options.defaultUriMatch,
|
||||
);
|
||||
return !matchesUri;
|
||||
}
|
||||
@ -1064,7 +1064,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillScript: AutofillScript,
|
||||
pageDetails: AutofillPageDetails,
|
||||
filledFields: { [id: string]: AutofillField },
|
||||
options: GenerateFillScriptOptions
|
||||
options: GenerateFillScriptOptions,
|
||||
): AutofillScript {
|
||||
if (!options.cipher.identity) {
|
||||
return null;
|
||||
@ -1095,7 +1095,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
AutofillService.isFieldMatch(
|
||||
f[attr],
|
||||
IdentityAutoFillConstants.FullNameFieldNames,
|
||||
IdentityAutoFillConstants.FullNameFieldNameValues
|
||||
IdentityAutoFillConstants.FullNameFieldNameValues,
|
||||
)
|
||||
) {
|
||||
fillFields.name = f;
|
||||
@ -1135,7 +1135,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
AutofillService.isFieldMatch(
|
||||
f[attr],
|
||||
IdentityAutoFillConstants.AddressFieldNames,
|
||||
IdentityAutoFillConstants.AddressFieldNameValues
|
||||
IdentityAutoFillConstants.AddressFieldNameValues,
|
||||
)
|
||||
) {
|
||||
fillFields.address = f;
|
||||
@ -1320,7 +1320,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
private static isFieldMatch(
|
||||
value: string,
|
||||
options: string[],
|
||||
containsOptions?: string[]
|
||||
containsOptions?: string[],
|
||||
): boolean {
|
||||
value = value
|
||||
.trim()
|
||||
@ -1355,14 +1355,14 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillFields: { [id: string]: AutofillField },
|
||||
filledFields: { [id: string]: AutofillField },
|
||||
dataProp: string,
|
||||
fieldProp?: string
|
||||
fieldProp?: string,
|
||||
) {
|
||||
fieldProp = fieldProp || dataProp;
|
||||
this.makeScriptActionWithValue(
|
||||
fillScript,
|
||||
cipherData[dataProp],
|
||||
fillFields[fieldProp],
|
||||
filledFields
|
||||
filledFields,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1381,7 +1381,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
fillScript: AutofillScript,
|
||||
dataValue: any,
|
||||
field: AutofillField,
|
||||
filledFields: { [id: string]: AutofillField }
|
||||
filledFields: { [id: string]: AutofillField },
|
||||
) {
|
||||
let doFill = false;
|
||||
if (AutofillService.hasValue(dataValue) && field) {
|
||||
@ -1431,7 +1431,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
canBeHidden: boolean,
|
||||
canBeReadOnly: boolean,
|
||||
mustBeEmpty: boolean,
|
||||
fillNewPassword: boolean
|
||||
fillNewPassword: boolean,
|
||||
) {
|
||||
const arr: AutofillField[] = [];
|
||||
pageDetails.fields.forEach((f) => {
|
||||
@ -1503,7 +1503,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
passwordField: AutofillField,
|
||||
canBeHidden: boolean,
|
||||
canBeReadOnly: boolean,
|
||||
withoutForm: boolean
|
||||
withoutForm: boolean,
|
||||
): AutofillField | null {
|
||||
let usernameField: AutofillField = null;
|
||||
for (let i = 0; i < pageDetails.fields.length; i++) {
|
||||
@ -1551,7 +1551,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
passwordField: AutofillField,
|
||||
canBeHidden: boolean,
|
||||
canBeReadOnly: boolean,
|
||||
withoutForm: boolean
|
||||
withoutForm: boolean,
|
||||
): AutofillField | null {
|
||||
let totpField: AutofillField = null;
|
||||
for (let i = 0; i < pageDetails.fields.length; i++) {
|
||||
@ -1659,7 +1659,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
property: string,
|
||||
name: string,
|
||||
prefix: string,
|
||||
separator = "="
|
||||
separator = "=",
|
||||
): boolean {
|
||||
if (name.indexOf(prefix + separator) === 0) {
|
||||
const sepIndex = name.indexOf(separator);
|
||||
@ -1806,7 +1806,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
*/
|
||||
static setFillScriptForFocus(
|
||||
filledFields: { [id: string]: AutofillField },
|
||||
fillScript: AutofillScript
|
||||
fillScript: AutofillScript,
|
||||
): AutofillScript {
|
||||
let lastField: AutofillField = null;
|
||||
let lastPasswordField: AutofillField = null;
|
||||
|
@ -31,7 +31,7 @@ describe("CollectAutofillContentService", () => {
|
||||
document.body.innerHTML = mockLoginForm;
|
||||
collectAutofillContentService = new CollectAutofillContentService(
|
||||
domElementVisibilityService,
|
||||
autofillOverlayContentService
|
||||
autofillOverlayContentService,
|
||||
);
|
||||
});
|
||||
|
||||
@ -68,7 +68,7 @@ describe("CollectAutofillContentService", () => {
|
||||
|
||||
expect(collectAutofillContentService["getFormattedPageDetails"]).toHaveBeenCalledWith({}, []);
|
||||
expect(
|
||||
collectAutofillContentService["queryAutofillFormAndFieldElements"]
|
||||
collectAutofillContentService["queryAutofillFormAndFieldElements"],
|
||||
).not.toHaveBeenCalled();
|
||||
expect(collectAutofillContentService["buildAutofillFormsData"]).not.toHaveBeenCalled();
|
||||
expect(collectAutofillContentService["buildAutofillFieldsData"]).not.toHaveBeenCalled();
|
||||
@ -102,7 +102,7 @@ describe("CollectAutofillContentService", () => {
|
||||
htmlMethod: formMethod,
|
||||
};
|
||||
const fieldElement = document.getElementById(
|
||||
usernameFieldId
|
||||
usernameFieldId,
|
||||
) as ElementWithOpId<FormFieldElement>;
|
||||
const autofillField: AutofillField = {
|
||||
opid: "__0",
|
||||
@ -156,7 +156,7 @@ describe("CollectAutofillContentService", () => {
|
||||
expect(collectAutofillContentService["getFormattedAutofillFormsData"]).toHaveBeenCalled();
|
||||
expect(collectAutofillContentService["getFormattedAutofillFieldsData"]).toHaveBeenCalled();
|
||||
expect(
|
||||
collectAutofillContentService["queryAutofillFormAndFieldElements"]
|
||||
collectAutofillContentService["queryAutofillFormAndFieldElements"],
|
||||
).not.toHaveBeenCalled();
|
||||
expect(collectAutofillContentService["buildAutofillFormsData"]).not.toHaveBeenCalled();
|
||||
expect(collectAutofillContentService["buildAutofillFieldsData"]).not.toHaveBeenCalled();
|
||||
@ -294,7 +294,7 @@ describe("CollectAutofillContentService", () => {
|
||||
it("returns the element with the opid property value matching the passed value", () => {
|
||||
const textInput = document.querySelector('input[type="text"]') as FormElementWithAttribute;
|
||||
const passwordInput = document.querySelector(
|
||||
'input[type="password"]'
|
||||
'input[type="password"]',
|
||||
) as FormElementWithAttribute;
|
||||
textInput.opid = "__0";
|
||||
passwordInput.opid = "__1";
|
||||
@ -311,7 +311,7 @@ describe("CollectAutofillContentService", () => {
|
||||
it("returns the first of the element with an `opid` value matching the passed value and emits a console warning if multiple fields contain the same `opid`", () => {
|
||||
const textInput = document.querySelector('input[type="text"]') as FormElementWithAttribute;
|
||||
const passwordInput = document.querySelector(
|
||||
'input[type="password"]'
|
||||
'input[type="password"]',
|
||||
) as FormElementWithAttribute;
|
||||
jest.spyOn(console, "warn").mockImplementationOnce(jest.fn());
|
||||
textInput.opid = "__1";
|
||||
@ -330,7 +330,7 @@ describe("CollectAutofillContentService", () => {
|
||||
it("returns the element at the index position (parsed from passed opid) of all AutofillField elements when the passed opid value cannot be found", () => {
|
||||
const textInput = document.querySelector('input[type="text"]') as FormElementWithAttribute;
|
||||
const passwordInput = document.querySelector(
|
||||
'input[type="password"]'
|
||||
'input[type="password"]',
|
||||
) as FormElementWithAttribute;
|
||||
textInput.opid = undefined;
|
||||
passwordInput.opid = "__1";
|
||||
@ -387,7 +387,7 @@ describe("CollectAutofillContentService", () => {
|
||||
jest.spyOn(collectAutofillContentService as any, "getFormActionAttribute");
|
||||
|
||||
const autofillFormsData = collectAutofillContentService["buildAutofillFormsData"](
|
||||
formElements as Node[]
|
||||
formElements as Node[],
|
||||
);
|
||||
|
||||
expect(collectAutofillContentService["getFormActionAttribute"]).not.toHaveBeenCalled();
|
||||
@ -452,13 +452,13 @@ describe("CollectAutofillContentService", () => {
|
||||
const { formFieldElements } =
|
||||
collectAutofillContentService["queryAutofillFormAndFieldElements"]();
|
||||
const autofillFieldsPromise = collectAutofillContentService["buildAutofillFieldsData"](
|
||||
formFieldElements as FormFieldElement[]
|
||||
formFieldElements as FormFieldElement[],
|
||||
);
|
||||
const autofillFieldsData = await Promise.resolve(autofillFieldsPromise);
|
||||
|
||||
expect(collectAutofillContentService["getAutofillFieldElements"]).toHaveBeenCalledWith(
|
||||
100,
|
||||
formFieldElements
|
||||
formFieldElements,
|
||||
);
|
||||
expect(collectAutofillContentService["buildAutofillFieldItem"]).toHaveBeenCalledTimes(2);
|
||||
expect(autofillFieldsPromise).toBeInstanceOf(Promise);
|
||||
@ -595,12 +595,12 @@ describe("CollectAutofillContentService", () => {
|
||||
expect(collectAutofillContentService["getPropertyOrAttribute"]).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
spanElement,
|
||||
"type"
|
||||
"type",
|
||||
);
|
||||
expect(collectAutofillContentService["getPropertyOrAttribute"]).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
textAreaInput,
|
||||
"type"
|
||||
"type",
|
||||
);
|
||||
expect(formElements).toEqual([spanElement, textAreaInput]);
|
||||
});
|
||||
@ -799,7 +799,7 @@ describe("CollectAutofillContentService", () => {
|
||||
viewable: true,
|
||||
};
|
||||
const usernameInput = document.getElementById(
|
||||
usernameField.id
|
||||
usernameField.id,
|
||||
) as ElementWithOpId<FillableFormFieldElement>;
|
||||
usernameInput.opid = "__0";
|
||||
collectAutofillContentService["autofillFieldElements"].set(usernameInput, existingFieldData);
|
||||
@ -812,12 +812,12 @@ describe("CollectAutofillContentService", () => {
|
||||
|
||||
const autofillFieldItem = await collectAutofillContentService["buildAutofillFieldItem"](
|
||||
usernameInput,
|
||||
0
|
||||
0,
|
||||
);
|
||||
|
||||
expect(collectAutofillContentService["getAutofillFieldMaxLength"]).not.toHaveBeenCalled();
|
||||
expect(
|
||||
collectAutofillContentService["domElementVisibilityService"].isFormFieldViewable
|
||||
collectAutofillContentService["domElementVisibilityService"].isFormFieldViewable,
|
||||
).not.toHaveBeenCalled();
|
||||
expect(collectAutofillContentService["getPropertyOrAttribute"]).not.toHaveBeenCalled();
|
||||
expect(collectAutofillContentService["getElementValue"]).not.toHaveBeenCalled();
|
||||
@ -834,7 +834,7 @@ describe("CollectAutofillContentService", () => {
|
||||
<span id="${spanElementId}" class="${spanElementClasses}" tabindex="${spanElementTabIndex}" title="${spanElementTitle}">Span Element</span>
|
||||
`;
|
||||
const spanElement = document.getElementById(
|
||||
spanElementId
|
||||
spanElementId,
|
||||
) as ElementWithOpId<FormFieldElement>;
|
||||
jest.spyOn(collectAutofillContentService as any, "getAutofillFieldMaxLength");
|
||||
jest
|
||||
@ -845,44 +845,44 @@ describe("CollectAutofillContentService", () => {
|
||||
|
||||
const autofillFieldItem = await collectAutofillContentService["buildAutofillFieldItem"](
|
||||
spanElement,
|
||||
index
|
||||
index,
|
||||
);
|
||||
|
||||
expect(collectAutofillContentService["getAutofillFieldMaxLength"]).toHaveBeenCalledWith(
|
||||
spanElement
|
||||
spanElement,
|
||||
);
|
||||
expect(
|
||||
collectAutofillContentService["domElementVisibilityService"].isFormFieldViewable
|
||||
collectAutofillContentService["domElementVisibilityService"].isFormFieldViewable,
|
||||
).toHaveBeenCalledWith(spanElement);
|
||||
expect(collectAutofillContentService["getPropertyOrAttribute"]).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
spanElement,
|
||||
"id"
|
||||
"id",
|
||||
);
|
||||
expect(collectAutofillContentService["getPropertyOrAttribute"]).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
spanElement,
|
||||
"name"
|
||||
"name",
|
||||
);
|
||||
expect(collectAutofillContentService["getPropertyOrAttribute"]).toHaveBeenNthCalledWith(
|
||||
3,
|
||||
spanElement,
|
||||
"class"
|
||||
"class",
|
||||
);
|
||||
expect(collectAutofillContentService["getPropertyOrAttribute"]).toHaveBeenNthCalledWith(
|
||||
4,
|
||||
spanElement,
|
||||
"tabindex"
|
||||
"tabindex",
|
||||
);
|
||||
expect(collectAutofillContentService["getPropertyOrAttribute"]).toHaveBeenNthCalledWith(
|
||||
5,
|
||||
spanElement,
|
||||
"title"
|
||||
"title",
|
||||
);
|
||||
expect(collectAutofillContentService["getPropertyOrAttribute"]).toHaveBeenNthCalledWith(
|
||||
6,
|
||||
spanElement,
|
||||
"tagName"
|
||||
"tagName",
|
||||
);
|
||||
expect(collectAutofillContentService["getElementValue"]).not.toHaveBeenCalled();
|
||||
expect(autofillFieldItem).toEqual({
|
||||
@ -942,7 +942,7 @@ describe("CollectAutofillContentService", () => {
|
||||
const formElement = document.querySelector("form");
|
||||
formElement.opid = "form-opid";
|
||||
const usernameInput = document.getElementById(
|
||||
usernameField.id
|
||||
usernameField.id,
|
||||
) as ElementWithOpId<FillableFormFieldElement>;
|
||||
jest.spyOn(collectAutofillContentService as any, "getAutofillFieldMaxLength");
|
||||
jest
|
||||
@ -953,7 +953,7 @@ describe("CollectAutofillContentService", () => {
|
||||
|
||||
const autofillFieldItem = await collectAutofillContentService["buildAutofillFieldItem"](
|
||||
usernameInput,
|
||||
index
|
||||
index,
|
||||
);
|
||||
|
||||
expect(autofillFieldItem).toEqual({
|
||||
@ -1027,7 +1027,7 @@ describe("CollectAutofillContentService", () => {
|
||||
const formElement = document.querySelector("form");
|
||||
formElement.opid = "form-opid";
|
||||
const hiddenInput = document.getElementById(
|
||||
hiddenField.id
|
||||
hiddenField.id,
|
||||
) as ElementWithOpId<FillableFormFieldElement>;
|
||||
jest.spyOn(collectAutofillContentService as any, "getAutofillFieldMaxLength");
|
||||
jest
|
||||
@ -1038,7 +1038,7 @@ describe("CollectAutofillContentService", () => {
|
||||
|
||||
const autofillFieldItem = await collectAutofillContentService["buildAutofillFieldItem"](
|
||||
hiddenInput,
|
||||
index
|
||||
index,
|
||||
);
|
||||
|
||||
expect(autofillFieldItem).toEqual({
|
||||
@ -1086,7 +1086,7 @@ describe("CollectAutofillContentService", () => {
|
||||
const labelTag = collectAutofillContentService["createAutofillFieldLabelTag"](element);
|
||||
|
||||
expect(collectAutofillContentService["createLabelElementsTag"]).toHaveBeenCalledWith(
|
||||
new Set(element.labels)
|
||||
new Set(element.labels),
|
||||
);
|
||||
expect(document.querySelectorAll).not.toHaveBeenCalled();
|
||||
expect(labelTag).toEqual("Username");
|
||||
@ -1104,7 +1104,7 @@ describe("CollectAutofillContentService", () => {
|
||||
|
||||
expect(document.querySelectorAll).toHaveBeenCalledWith(`label[for="${element.id}"]`);
|
||||
expect(collectAutofillContentService["createLabelElementsTag"]).toHaveBeenCalledWith(
|
||||
new Set([elementLabel])
|
||||
new Set([elementLabel]),
|
||||
);
|
||||
expect(labelTag).toEqual("Country");
|
||||
});
|
||||
@ -1122,7 +1122,7 @@ describe("CollectAutofillContentService", () => {
|
||||
expect(document.querySelectorAll).not.toHaveBeenCalledWith(`label[for="${element.id}"]`);
|
||||
expect(document.querySelectorAll).toHaveBeenCalledWith(`label[for="${element.name}"]`);
|
||||
expect(collectAutofillContentService["createLabelElementsTag"]).toHaveBeenCalledWith(
|
||||
new Set([elementLabel])
|
||||
new Set([elementLabel]),
|
||||
);
|
||||
expect(labelTag).toEqual("Country");
|
||||
});
|
||||
@ -1139,10 +1139,10 @@ describe("CollectAutofillContentService", () => {
|
||||
const labelTag = collectAutofillContentService["createAutofillFieldLabelTag"](element);
|
||||
|
||||
expect(document.querySelectorAll).toHaveBeenCalledWith(
|
||||
`label[for="${element.id}"], label[for="${element.name}"]`
|
||||
`label[for="${element.id}"], label[for="${element.name}"]`,
|
||||
);
|
||||
expect(collectAutofillContentService["createLabelElementsTag"]).toHaveBeenCalledWith(
|
||||
new Set([elementLabel])
|
||||
new Set([elementLabel]),
|
||||
);
|
||||
expect(labelTag).toEqual("Country");
|
||||
});
|
||||
@ -1158,7 +1158,7 @@ describe("CollectAutofillContentService", () => {
|
||||
const labelTag = collectAutofillContentService["createAutofillFieldLabelTag"](element);
|
||||
|
||||
expect(collectAutofillContentService["createLabelElementsTag"]).toHaveBeenCalledWith(
|
||||
new Set([elementLabel])
|
||||
new Set([elementLabel]),
|
||||
);
|
||||
expect(labelTag).toEqual("Username");
|
||||
});
|
||||
@ -1178,7 +1178,7 @@ describe("CollectAutofillContentService", () => {
|
||||
const labelTag = collectAutofillContentService["createAutofillFieldLabelTag"](element);
|
||||
|
||||
expect(collectAutofillContentService["createLabelElementsTag"]).toHaveBeenCalledWith(
|
||||
new Set([elementLabel])
|
||||
new Set([elementLabel]),
|
||||
);
|
||||
expect(labelTag).toEqual("Username");
|
||||
});
|
||||
@ -1275,10 +1275,10 @@ describe("CollectAutofillContentService", () => {
|
||||
const labelTag = collectAutofillContentService["createLabelElementsTag"](new Set(labels));
|
||||
|
||||
expect(
|
||||
collectAutofillContentService["trimAndRemoveNonPrintableText"]
|
||||
collectAutofillContentService["trimAndRemoveNonPrintableText"],
|
||||
).toHaveBeenNthCalledWith(1, firstLabelText);
|
||||
expect(
|
||||
collectAutofillContentService["trimAndRemoveNonPrintableText"]
|
||||
collectAutofillContentService["trimAndRemoveNonPrintableText"],
|
||||
).toHaveBeenNthCalledWith(2, secondLabelText);
|
||||
expect(labelTag).toEqual(`${firstLabelText}${secondLabelText}`);
|
||||
});
|
||||
@ -1406,7 +1406,7 @@ describe("CollectAutofillContentService", () => {
|
||||
</table>
|
||||
`;
|
||||
const targetTableCellInput = document.querySelector(
|
||||
'input[name="password"]'
|
||||
'input[name="password"]',
|
||||
) as HTMLInputElement;
|
||||
|
||||
const targetTableCellLabel =
|
||||
@ -1433,7 +1433,7 @@ describe("CollectAutofillContentService", () => {
|
||||
</table>
|
||||
`;
|
||||
const targetTableCellInput = document.querySelector(
|
||||
'input[name="auth-code"]'
|
||||
'input[name="auth-code"]',
|
||||
) as HTMLInputElement;
|
||||
|
||||
const targetTableCellLabel =
|
||||
@ -1455,7 +1455,7 @@ describe("CollectAutofillContentService", () => {
|
||||
</table>
|
||||
`;
|
||||
const targetTableCellInput = document.querySelector(
|
||||
'input[name="password"]'
|
||||
'input[name="password"]',
|
||||
) as HTMLInputElement;
|
||||
|
||||
const targetTableCellLabel =
|
||||
@ -1482,7 +1482,7 @@ describe("CollectAutofillContentService", () => {
|
||||
</table>
|
||||
`;
|
||||
const targetTableCellInput = document.querySelector(
|
||||
'input[name="password"]'
|
||||
'input[name="password"]',
|
||||
) as HTMLInputElement;
|
||||
|
||||
const targetTableCellLabel =
|
||||
@ -1508,7 +1508,7 @@ describe("CollectAutofillContentService", () => {
|
||||
</table>
|
||||
`;
|
||||
const targetTableCellInput = document.querySelector(
|
||||
'input[name="auth-code"]'
|
||||
'input[name="auth-code"]',
|
||||
) as HTMLInputElement;
|
||||
|
||||
const targetTableCellLabel =
|
||||
@ -1573,7 +1573,7 @@ describe("CollectAutofillContentService", () => {
|
||||
const element = document.querySelector("#username-id");
|
||||
const textNode = element.previousSibling;
|
||||
const parsedTextContent = collectAutofillContentService["trimAndRemoveNonPrintableText"](
|
||||
textNode.nodeValue
|
||||
textNode.nodeValue,
|
||||
);
|
||||
jest.spyOn(collectAutofillContentService as any, "trimAndRemoveNonPrintableText");
|
||||
|
||||
@ -1581,7 +1581,7 @@ describe("CollectAutofillContentService", () => {
|
||||
|
||||
expect(textNode.nodeType).toEqual(Node.TEXT_NODE);
|
||||
expect(collectAutofillContentService["trimAndRemoveNonPrintableText"]).toHaveBeenCalledWith(
|
||||
textNode.nodeValue
|
||||
textNode.nodeValue,
|
||||
);
|
||||
expect(textContent).toEqual(parsedTextContent);
|
||||
});
|
||||
@ -1600,7 +1600,7 @@ describe("CollectAutofillContentService", () => {
|
||||
|
||||
expect(element.nodeType).toEqual(Node.ELEMENT_NODE);
|
||||
expect(collectAutofillContentService["trimAndRemoveNonPrintableText"]).toHaveBeenCalledWith(
|
||||
element.textContent
|
||||
element.textContent,
|
||||
);
|
||||
expect(textContent).toEqual(element.textContent);
|
||||
});
|
||||
@ -1735,20 +1735,20 @@ describe("CollectAutofillContentService", () => {
|
||||
|
||||
const textInputValue = collectAutofillContentService["getPropertyOrAttribute"](
|
||||
textInput,
|
||||
"value"
|
||||
"value",
|
||||
);
|
||||
const textInputId = collectAutofillContentService["getPropertyOrAttribute"](textInput, "id");
|
||||
const textInputBaseURI = collectAutofillContentService["getPropertyOrAttribute"](
|
||||
textInput,
|
||||
"baseURI"
|
||||
"baseURI",
|
||||
);
|
||||
const textInputAutofocus = collectAutofillContentService["getPropertyOrAttribute"](
|
||||
textInput,
|
||||
"autofocus"
|
||||
"autofocus",
|
||||
);
|
||||
const checkboxInputChecked = collectAutofillContentService["getPropertyOrAttribute"](
|
||||
checkboxInput,
|
||||
"checked"
|
||||
"checked",
|
||||
);
|
||||
|
||||
expect(textInput.getAttribute).not.toHaveBeenCalled();
|
||||
@ -1767,7 +1767,7 @@ describe("CollectAutofillContentService", () => {
|
||||
|
||||
const textInputUniqueAttribute = collectAutofillContentService["getPropertyOrAttribute"](
|
||||
textInput,
|
||||
"data-unique-attribute"
|
||||
"data-unique-attribute",
|
||||
);
|
||||
|
||||
expect(textInputUniqueAttribute).toEqual("unique-value");
|
||||
@ -1780,7 +1780,7 @@ describe("CollectAutofillContentService", () => {
|
||||
|
||||
const textInputNonExistentAttribute = collectAutofillContentService["getPropertyOrAttribute"](
|
||||
textInput,
|
||||
"non-existent-attribute"
|
||||
"non-existent-attribute",
|
||||
);
|
||||
|
||||
expect(textInputNonExistentAttribute).toEqual(null);
|
||||
@ -1841,14 +1841,14 @@ describe("CollectAutofillContentService", () => {
|
||||
<input id="long-value-hidden-input" type="hidden" value="’Twas brillig, and the slithy toves | Did gyre and gimble in the wabe: | All mimsy were the borogoves, | And the mome raths outgrabe. | “Beware the Jabberwock, my son! | The jaws that bite, the claws that catch! | Beware the Jubjub bird, and shun | The frumious Bandersnatch!” | He took his vorpal sword in hand; | Long time the manxome foe he sought— | So rested he by the Tumtum tree | And stood awhile in thought. | And, as in uffish thought he stood, | The Jabberwock, with eyes of flame, | Came whiffling through the tulgey wood, | And burbled as it came! | One, two! One, two! And through and through | The vorpal blade went snicker-snack! | He left it dead, and with its head | He went galumphing back. | “And hast thou slain the Jabberwock? | Come to my arms, my beamish boy! | O frabjous day! Callooh! Callay!” | He chortled in his joy. | ’Twas brillig, and the slithy toves | Did gyre and gimble in the wabe: | All mimsy were the borogoves, | And the mome raths outgrabe." />
|
||||
`;
|
||||
const longValueHiddenInput = document.querySelector(
|
||||
"#long-value-hidden-input"
|
||||
"#long-value-hidden-input",
|
||||
) as HTMLInputElement;
|
||||
|
||||
const longHiddenValue =
|
||||
collectAutofillContentService["getElementValue"](longValueHiddenInput);
|
||||
|
||||
expect(longHiddenValue).toEqual(
|
||||
"’Twas brillig, and the slithy toves | Did gyre and gimble in the wabe: | All mimsy were the borogoves, | And the mome raths outgrabe. | “Beware the Jabberwock, my son! | The jaws that bite, the claws that catch! | Beware the Jubjub bird, and shun | The f...SNIPPED"
|
||||
"’Twas brillig, and the slithy toves | Did gyre and gimble in the wabe: | All mimsy were the borogoves, | And the mome raths outgrabe. | “Beware the Jabberwock, my son! | The jaws that bite, the claws that catch! | Beware the Jubjub bird, and shun | The f...SNIPPED",
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1866,7 +1866,7 @@ describe("CollectAutofillContentService", () => {
|
||||
`;
|
||||
const selectWithOptions = document.querySelector("#select-with-options") as HTMLSelectElement;
|
||||
const selectWithoutOptions = document.querySelector(
|
||||
"#select-without-options"
|
||||
"#select-without-options",
|
||||
) as HTMLSelectElement;
|
||||
|
||||
const selectWithOptionsOptions =
|
||||
@ -1925,7 +1925,7 @@ describe("CollectAutofillContentService", () => {
|
||||
document.body,
|
||||
[],
|
||||
callbackFilter,
|
||||
true
|
||||
true,
|
||||
);
|
||||
|
||||
expect(collectAutofillContentService["buildTreeWalkerNodesQueryResults"]).toBeCalledTimes(2);
|
||||
@ -1946,7 +1946,7 @@ describe("CollectAutofillContentService", () => {
|
||||
document.body,
|
||||
[],
|
||||
callbackFilter,
|
||||
false
|
||||
false,
|
||||
);
|
||||
|
||||
expect(collectAutofillContentService["mutationObserver"].observe).not.toBeCalled();
|
||||
@ -1993,10 +1993,10 @@ describe("CollectAutofillContentService", () => {
|
||||
expect(collectAutofillContentService["noFieldsFound"]).toEqual(false);
|
||||
expect(collectAutofillContentService["isAutofillElementNodeMutated"]).toBeCalledWith(
|
||||
removedNodes,
|
||||
true
|
||||
true,
|
||||
);
|
||||
expect(collectAutofillContentService["isAutofillElementNodeMutated"]).toBeCalledWith(
|
||||
addedNodes
|
||||
addedNodes,
|
||||
);
|
||||
});
|
||||
|
||||
@ -2048,7 +2048,7 @@ describe("CollectAutofillContentService", () => {
|
||||
expect(collectAutofillContentService["handleWindowLocationMutation"]).toBeCalled();
|
||||
expect(collectAutofillContentService["isAutofillElementNodeMutated"]).not.toBeCalled();
|
||||
expect(
|
||||
collectAutofillContentService["handleAutofillElementAttributeMutation"]
|
||||
collectAutofillContentService["handleAutofillElementAttributeMutation"],
|
||||
).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
@ -2170,7 +2170,7 @@ describe("CollectAutofillContentService", () => {
|
||||
expect(collectAutofillContentService["updateAutofillFormElementData"]).toBeCalledWith(
|
||||
mutationRecord.attributeName,
|
||||
mutationRecord.target,
|
||||
autofillForm
|
||||
autofillForm,
|
||||
);
|
||||
});
|
||||
|
||||
@ -2217,7 +2217,7 @@ describe("CollectAutofillContentService", () => {
|
||||
expect(collectAutofillContentService["updateAutofillFieldElementData"]).toBeCalledWith(
|
||||
mutationRecord.attributeName,
|
||||
mutationRecord.target,
|
||||
autofillField
|
||||
autofillField,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -2240,12 +2240,12 @@ describe("CollectAutofillContentService", () => {
|
||||
collectAutofillContentService["updateAutofillFormElementData"](
|
||||
attribute,
|
||||
formElement,
|
||||
autofillForm
|
||||
autofillForm,
|
||||
);
|
||||
|
||||
expect(collectAutofillContentService["autofillFormElements"].set).toBeCalledWith(
|
||||
formElement,
|
||||
autofillForm
|
||||
autofillForm,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -2256,7 +2256,7 @@ describe("CollectAutofillContentService", () => {
|
||||
collectAutofillContentService["updateAutofillFormElementData"](
|
||||
"aria-label",
|
||||
formElement,
|
||||
autofillForm
|
||||
autofillForm,
|
||||
);
|
||||
|
||||
expect(collectAutofillContentService["autofillFormElements"].set).not.toBeCalled();
|
||||
@ -2305,12 +2305,12 @@ describe("CollectAutofillContentService", () => {
|
||||
await collectAutofillContentService["updateAutofillFieldElementData"](
|
||||
attribute,
|
||||
fieldElement,
|
||||
autofillField
|
||||
autofillField,
|
||||
);
|
||||
|
||||
expect(collectAutofillContentService["autofillFieldElements"].set).toBeCalledWith(
|
||||
fieldElement,
|
||||
autofillField
|
||||
autofillField,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -2318,7 +2318,7 @@ describe("CollectAutofillContentService", () => {
|
||||
it("will check the dom element's visibility if the `style` or `class` attribute has updated ", async () => {
|
||||
jest.spyOn(
|
||||
collectAutofillContentService["domElementVisibilityService"],
|
||||
"isFormFieldViewable"
|
||||
"isFormFieldViewable",
|
||||
);
|
||||
const attributes = ["class", "style"];
|
||||
|
||||
@ -2326,11 +2326,11 @@ describe("CollectAutofillContentService", () => {
|
||||
await collectAutofillContentService["updateAutofillFieldElementData"](
|
||||
attribute,
|
||||
fieldElement,
|
||||
autofillField
|
||||
autofillField,
|
||||
);
|
||||
|
||||
expect(
|
||||
collectAutofillContentService["domElementVisibilityService"].isFormFieldViewable
|
||||
collectAutofillContentService["domElementVisibilityService"].isFormFieldViewable,
|
||||
).toBeCalledWith(fieldElement);
|
||||
}
|
||||
});
|
||||
@ -2341,7 +2341,7 @@ describe("CollectAutofillContentService", () => {
|
||||
await collectAutofillContentService["updateAutofillFieldElementData"](
|
||||
"random-attribute",
|
||||
fieldElement,
|
||||
autofillField
|
||||
autofillField,
|
||||
);
|
||||
|
||||
expect(collectAutofillContentService["autofillFieldElements"].set).not.toBeCalled();
|
||||
|
@ -31,7 +31,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
|
||||
constructor(
|
||||
domElementVisibilityService: DomElementVisibilityService,
|
||||
autofillOverlayContentService?: AutofillOverlayContentService
|
||||
autofillOverlayContentService?: AutofillOverlayContentService,
|
||||
) {
|
||||
this.domElementVisibilityService = domElementVisibilityService;
|
||||
this.autofillOverlayContentService = autofillOverlayContentService;
|
||||
@ -56,7 +56,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
if (!this.domRecentlyMutated && this.autofillFieldElements.size) {
|
||||
return this.getFormattedPageDetails(
|
||||
this.getFormattedAutofillFormsData(),
|
||||
this.getFormattedAutofillFieldsData()
|
||||
this.getFormattedAutofillFieldsData(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
const autofillFormsData: Record<string, AutofillForm> =
|
||||
this.buildAutofillFormsData(formElements);
|
||||
const autofillFieldsData: AutofillField[] = await this.buildAutofillFieldsData(
|
||||
formFieldElements as FormFieldElement[]
|
||||
formFieldElements as FormFieldElement[],
|
||||
);
|
||||
this.sortAutofillFieldElementsMap();
|
||||
|
||||
@ -89,7 +89,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
? cachedFormFieldElements
|
||||
: this.getAutofillFieldElements();
|
||||
const fieldElementsWithOpid = formFieldElements.filter(
|
||||
(fieldElement) => (fieldElement as ElementWithOpId<FormFieldElement>).opid === opid
|
||||
(fieldElement) => (fieldElement as ElementWithOpId<FormFieldElement>).opid === opid,
|
||||
) as ElementWithOpId<FormFieldElement>[];
|
||||
|
||||
if (!fieldElementsWithOpid.length) {
|
||||
@ -117,7 +117,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
queryAllTreeWalkerNodes(
|
||||
rootNode: Node,
|
||||
filterCallback: CallableFunction,
|
||||
isObservingShadowRoot = true
|
||||
isObservingShadowRoot = true,
|
||||
): Node[] {
|
||||
const treeWalkerQueryResults: Node[] = [];
|
||||
|
||||
@ -125,7 +125,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
rootNode,
|
||||
treeWalkerQueryResults,
|
||||
filterCallback,
|
||||
isObservingShadowRoot
|
||||
isObservingShadowRoot,
|
||||
);
|
||||
|
||||
return treeWalkerQueryResults;
|
||||
@ -141,7 +141,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
}
|
||||
|
||||
this.autofillFieldElements = new Map(
|
||||
[...this.autofillFieldElements].sort((a, b) => a[1].elementNumber - b[1].elementNumber)
|
||||
[...this.autofillFieldElements].sort((a, b) => a[1].elementNumber - b[1].elementNumber),
|
||||
);
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
*/
|
||||
private getFormattedPageDetails(
|
||||
autofillFormsData: Record<string, AutofillForm>,
|
||||
autofillFieldsData: AutofillField[]
|
||||
autofillFieldsData: AutofillField[],
|
||||
): AutofillPageDetails {
|
||||
return {
|
||||
title: document.title,
|
||||
@ -231,7 +231,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
* @private
|
||||
*/
|
||||
private async buildAutofillFieldsData(
|
||||
formFieldElements: FormFieldElement[]
|
||||
formFieldElements: FormFieldElement[],
|
||||
): Promise<AutofillField[]> {
|
||||
const autofillFieldElements = this.getAutofillFieldElements(100, formFieldElements);
|
||||
const autofillFieldDataPromises = autofillFieldElements.map(this.buildAutofillFieldItem);
|
||||
@ -250,12 +250,12 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
*/
|
||||
private getAutofillFieldElements(
|
||||
fieldsLimit?: number,
|
||||
previouslyFoundFormFieldElements?: FormFieldElement[]
|
||||
previouslyFoundFormFieldElements?: FormFieldElement[],
|
||||
): FormFieldElement[] {
|
||||
const formFieldElements =
|
||||
previouslyFoundFormFieldElements ||
|
||||
(this.queryAllTreeWalkerNodes(document.documentElement, (node: Node) =>
|
||||
this.isNodeFormFieldElement(node)
|
||||
this.isNodeFormFieldElement(node),
|
||||
) as FormFieldElement[]);
|
||||
|
||||
if (!fieldsLimit || formFieldElements.length <= fieldsLimit) {
|
||||
@ -298,7 +298,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
*/
|
||||
private buildAutofillFieldItem = async (
|
||||
element: ElementWithOpId<FormFieldElement>,
|
||||
index: number
|
||||
index: number,
|
||||
): Promise<AutofillField> => {
|
||||
element.opid = `__${index}`;
|
||||
|
||||
@ -328,7 +328,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
this.autofillFieldElements.set(element, autofillFieldBase);
|
||||
this.autofillOverlayContentService?.setupAutofillOverlayListenerOnField(
|
||||
element,
|
||||
autofillFieldBase
|
||||
autofillFieldBase,
|
||||
);
|
||||
return autofillFieldBase;
|
||||
}
|
||||
@ -397,7 +397,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
private getAttributeBoolean(
|
||||
element: ElementWithOpId<FormFieldElement>,
|
||||
attributeName: string,
|
||||
checkString = false
|
||||
checkString = false,
|
||||
): boolean {
|
||||
if (checkString) {
|
||||
return this.getPropertyOrAttribute(element, attributeName) === "true";
|
||||
@ -415,7 +415,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
*/
|
||||
private getAttributeLowerCase(
|
||||
element: ElementWithOpId<FormFieldElement>,
|
||||
attributeName: string
|
||||
attributeName: string,
|
||||
): string {
|
||||
return this.getPropertyOrAttribute(element, attributeName)?.toLowerCase();
|
||||
}
|
||||
@ -479,7 +479,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
* @private
|
||||
*/
|
||||
private queryElementLabels(
|
||||
element: FillableFormFieldElement
|
||||
element: FillableFormFieldElement,
|
||||
): NodeListOf<HTMLLabelElement> | null {
|
||||
let labelQuerySelectors = element.id ? `label[for="${element.id}"]` : "";
|
||||
if (element.name) {
|
||||
@ -494,7 +494,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
}
|
||||
|
||||
return (element.getRootNode() as Document | ShadowRoot).querySelectorAll(
|
||||
labelQuerySelectors.replace(/\n/g, "")
|
||||
labelQuerySelectors.replace(/\n/g, ""),
|
||||
);
|
||||
}
|
||||
|
||||
@ -645,7 +645,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
}
|
||||
|
||||
return this.trimAndRemoveNonPrintableText(
|
||||
element.textContent || (element as HTMLElement).innerText
|
||||
element.textContent || (element as HTMLElement).innerText,
|
||||
);
|
||||
}
|
||||
|
||||
@ -869,7 +869,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
rootNode: Node,
|
||||
treeWalkerQueryResults: Node[],
|
||||
filterCallback: CallableFunction,
|
||||
isObservingShadowRoot: boolean
|
||||
isObservingShadowRoot: boolean,
|
||||
) {
|
||||
const treeWalker = document?.createTreeWalker(rootNode, NodeFilter.SHOW_ELEMENT);
|
||||
let currentNode = treeWalker?.currentNode;
|
||||
@ -893,7 +893,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
nodeShadowRoot,
|
||||
treeWalkerQueryResults,
|
||||
filterCallback,
|
||||
isObservingShadowRoot
|
||||
isObservingShadowRoot,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1002,7 +1002,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
|
||||
const childNodes = this.queryAllTreeWalkerNodes(
|
||||
node,
|
||||
(node: Node) => node instanceof HTMLFormElement || this.isNodeFormFieldElement(node)
|
||||
(node: Node) => node instanceof HTMLFormElement || this.isNodeFormFieldElement(node),
|
||||
) as HTMLElement[];
|
||||
if (childNodes.length) {
|
||||
isElementMutated = true;
|
||||
@ -1014,7 +1014,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
const node = mutatedElements[elementIndex];
|
||||
if (isRemovingNodes) {
|
||||
this.deleteCachedAutofillElement(
|
||||
node as ElementWithOpId<HTMLFormElement> | ElementWithOpId<FormFieldElement>
|
||||
node as ElementWithOpId<HTMLFormElement> | ElementWithOpId<FormFieldElement>,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@ -1040,7 +1040,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
* @private
|
||||
*/
|
||||
private deleteCachedAutofillElement(
|
||||
element: ElementWithOpId<HTMLFormElement> | ElementWithOpId<FormFieldElement>
|
||||
element: ElementWithOpId<HTMLFormElement> | ElementWithOpId<FormFieldElement>,
|
||||
) {
|
||||
if (element instanceof HTMLFormElement && this.autofillFormElements.has(element)) {
|
||||
this.autofillFormElements.delete(element);
|
||||
@ -1064,7 +1064,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
|
||||
this.updateAutofillElementsAfterMutationTimeout = setTimeout(
|
||||
this.getPageDetails.bind(this),
|
||||
this.updateAfterMutationTimeoutDelay
|
||||
this.updateAfterMutationTimeoutDelay,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1081,21 +1081,21 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
|
||||
const attributeName = mutation.attributeName?.toLowerCase();
|
||||
const autofillForm = this.autofillFormElements.get(
|
||||
targetElement as ElementWithOpId<HTMLFormElement>
|
||||
targetElement as ElementWithOpId<HTMLFormElement>,
|
||||
);
|
||||
|
||||
if (autofillForm) {
|
||||
this.updateAutofillFormElementData(
|
||||
attributeName,
|
||||
targetElement as ElementWithOpId<HTMLFormElement>,
|
||||
autofillForm
|
||||
autofillForm,
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const autofillField = this.autofillFieldElements.get(
|
||||
targetElement as ElementWithOpId<FormFieldElement>
|
||||
targetElement as ElementWithOpId<FormFieldElement>,
|
||||
);
|
||||
if (!autofillField) {
|
||||
return;
|
||||
@ -1104,7 +1104,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
this.updateAutofillFieldElementData(
|
||||
attributeName,
|
||||
targetElement as ElementWithOpId<FormFieldElement>,
|
||||
autofillField
|
||||
autofillField,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1118,7 +1118,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
private updateAutofillFormElementData(
|
||||
attributeName: string,
|
||||
element: ElementWithOpId<HTMLFormElement>,
|
||||
dataTarget: AutofillForm
|
||||
dataTarget: AutofillForm,
|
||||
) {
|
||||
const updateAttribute = (dataTargetKey: string) => {
|
||||
this.updateAutofillDataAttribute({ element, attributeName, dataTarget, dataTargetKey });
|
||||
@ -1149,7 +1149,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte
|
||||
private async updateAutofillFieldElementData(
|
||||
attributeName: string,
|
||||
element: ElementWithOpId<FormFieldElement>,
|
||||
dataTarget: AutofillField
|
||||
dataTarget: AutofillField,
|
||||
) {
|
||||
const updateAttribute = (dataTargetKey: string) => {
|
||||
this.updateAutofillDataAttribute({ element, attributeName, dataTarget, dataTargetKey });
|
||||
|
@ -47,19 +47,18 @@ describe("DomElementVisibilityService", () => {
|
||||
jest.spyOn(domElementVisibilityService, "isElementHiddenByCss");
|
||||
jest.spyOn(domElementVisibilityService as any, "formFieldIsNotHiddenBehindAnotherElement");
|
||||
|
||||
const isFormFieldViewable = await domElementVisibilityService.isFormFieldViewable(
|
||||
usernameElement
|
||||
);
|
||||
const isFormFieldViewable =
|
||||
await domElementVisibilityService.isFormFieldViewable(usernameElement);
|
||||
|
||||
expect(isFormFieldViewable).toEqual(false);
|
||||
expect(usernameElement.getBoundingClientRect).toHaveBeenCalled();
|
||||
expect(domElementVisibilityService["isElementOutsideViewportBounds"]).toHaveBeenCalledWith(
|
||||
usernameElement,
|
||||
usernameElement.getBoundingClientRect()
|
||||
usernameElement.getBoundingClientRect(),
|
||||
);
|
||||
expect(domElementVisibilityService["isElementHiddenByCss"]).not.toHaveBeenCalled();
|
||||
expect(
|
||||
domElementVisibilityService["formFieldIsNotHiddenBehindAnotherElement"]
|
||||
domElementVisibilityService["formFieldIsNotHiddenBehindAnotherElement"],
|
||||
).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -72,21 +71,20 @@ describe("DomElementVisibilityService", () => {
|
||||
jest.spyOn(domElementVisibilityService, "isElementHiddenByCss").mockReturnValueOnce(true);
|
||||
jest.spyOn(domElementVisibilityService as any, "formFieldIsNotHiddenBehindAnotherElement");
|
||||
|
||||
const isFormFieldViewable = await domElementVisibilityService.isFormFieldViewable(
|
||||
usernameElement
|
||||
);
|
||||
const isFormFieldViewable =
|
||||
await domElementVisibilityService.isFormFieldViewable(usernameElement);
|
||||
|
||||
expect(isFormFieldViewable).toEqual(false);
|
||||
expect(usernameElement.getBoundingClientRect).toHaveBeenCalled();
|
||||
expect(domElementVisibilityService["isElementOutsideViewportBounds"]).toHaveBeenCalledWith(
|
||||
usernameElement,
|
||||
usernameElement.getBoundingClientRect()
|
||||
usernameElement.getBoundingClientRect(),
|
||||
);
|
||||
expect(domElementVisibilityService["isElementHiddenByCss"]).toHaveBeenCalledWith(
|
||||
usernameElement
|
||||
usernameElement,
|
||||
);
|
||||
expect(
|
||||
domElementVisibilityService["formFieldIsNotHiddenBehindAnotherElement"]
|
||||
domElementVisibilityService["formFieldIsNotHiddenBehindAnotherElement"],
|
||||
).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -101,21 +99,20 @@ describe("DomElementVisibilityService", () => {
|
||||
.spyOn(domElementVisibilityService as any, "formFieldIsNotHiddenBehindAnotherElement")
|
||||
.mockReturnValueOnce(false);
|
||||
|
||||
const isFormFieldViewable = await domElementVisibilityService.isFormFieldViewable(
|
||||
usernameElement
|
||||
);
|
||||
const isFormFieldViewable =
|
||||
await domElementVisibilityService.isFormFieldViewable(usernameElement);
|
||||
|
||||
expect(isFormFieldViewable).toEqual(false);
|
||||
expect(usernameElement.getBoundingClientRect).toHaveBeenCalled();
|
||||
expect(domElementVisibilityService["isElementOutsideViewportBounds"]).toHaveBeenCalledWith(
|
||||
usernameElement,
|
||||
usernameElement.getBoundingClientRect()
|
||||
usernameElement.getBoundingClientRect(),
|
||||
);
|
||||
expect(domElementVisibilityService["isElementHiddenByCss"]).toHaveBeenCalledWith(
|
||||
usernameElement
|
||||
usernameElement,
|
||||
);
|
||||
expect(
|
||||
domElementVisibilityService["formFieldIsNotHiddenBehindAnotherElement"]
|
||||
domElementVisibilityService["formFieldIsNotHiddenBehindAnotherElement"],
|
||||
).toHaveBeenCalledWith(usernameElement, usernameElement.getBoundingClientRect());
|
||||
});
|
||||
|
||||
@ -130,21 +127,20 @@ describe("DomElementVisibilityService", () => {
|
||||
.spyOn(domElementVisibilityService as any, "formFieldIsNotHiddenBehindAnotherElement")
|
||||
.mockReturnValueOnce(true);
|
||||
|
||||
const isFormFieldViewable = await domElementVisibilityService.isFormFieldViewable(
|
||||
usernameElement
|
||||
);
|
||||
const isFormFieldViewable =
|
||||
await domElementVisibilityService.isFormFieldViewable(usernameElement);
|
||||
|
||||
expect(isFormFieldViewable).toEqual(true);
|
||||
expect(usernameElement.getBoundingClientRect).toHaveBeenCalled();
|
||||
expect(domElementVisibilityService["isElementOutsideViewportBounds"]).toHaveBeenCalledWith(
|
||||
usernameElement,
|
||||
usernameElement.getBoundingClientRect()
|
||||
usernameElement.getBoundingClientRect(),
|
||||
);
|
||||
expect(domElementVisibilityService["isElementHiddenByCss"]).toHaveBeenCalledWith(
|
||||
usernameElement
|
||||
usernameElement,
|
||||
);
|
||||
expect(
|
||||
domElementVisibilityService["formFieldIsNotHiddenBehindAnotherElement"]
|
||||
domElementVisibilityService["formFieldIsNotHiddenBehindAnotherElement"],
|
||||
).toHaveBeenCalledWith(usernameElement, usernameElement.getBoundingClientRect());
|
||||
});
|
||||
});
|
||||
@ -186,12 +182,12 @@ describe("DomElementVisibilityService", () => {
|
||||
expect(isUsernameElementHidden).toEqual(true);
|
||||
expect(usernameElement.style.getPropertyValue).toHaveBeenCalled();
|
||||
expect(usernameElement.ownerDocument.defaultView.getComputedStyle).toHaveBeenCalledWith(
|
||||
usernameElement
|
||||
usernameElement,
|
||||
);
|
||||
expect(isPasswordElementHidden).toEqual(true);
|
||||
expect(passwordElement.style.getPropertyValue).toHaveBeenCalled();
|
||||
expect(passwordElement.ownerDocument.defaultView.getComputedStyle).toHaveBeenCalledWith(
|
||||
passwordElement
|
||||
passwordElement,
|
||||
);
|
||||
});
|
||||
|
||||
@ -391,7 +387,7 @@ describe("DomElementVisibilityService", () => {
|
||||
expect(formFieldIsNotHiddenBehindAnotherElement).toEqual(true);
|
||||
expect(document.elementFromPoint).toHaveBeenCalledWith(
|
||||
mockBoundingRect.left + mockBoundingRect.width / 2,
|
||||
mockBoundingRect.top + mockBoundingRect.height / 2
|
||||
mockBoundingRect.top + mockBoundingRect.height / 2,
|
||||
);
|
||||
expect(usernameElement.getBoundingClientRect).not.toHaveBeenCalled();
|
||||
});
|
||||
|
@ -67,7 +67,7 @@ class DomElementVisibilityService implements domElementVisibilityServiceInterfac
|
||||
private getElementStyle(element: HTMLElement, styleProperty: string): string {
|
||||
if (!this.cachedComputedStyle) {
|
||||
this.cachedComputedStyle = (element.ownerDocument.defaultView || window).getComputedStyle(
|
||||
element
|
||||
element,
|
||||
);
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ class DomElementVisibilityService implements domElementVisibilityServiceInterfac
|
||||
*/
|
||||
private isElementOutsideViewportBounds(
|
||||
targetElement: HTMLElement,
|
||||
targetElementBoundingClientRect: DOMRectReadOnly | null = null
|
||||
targetElementBoundingClientRect: DOMRectReadOnly | null = null,
|
||||
): boolean {
|
||||
const documentElement = targetElement.ownerDocument.documentElement;
|
||||
const documentElementWidth = documentElement.scrollWidth;
|
||||
@ -171,7 +171,7 @@ class DomElementVisibilityService implements domElementVisibilityServiceInterfac
|
||||
*/
|
||||
private formFieldIsNotHiddenBehindAnotherElement(
|
||||
targetElement: FormFieldElement,
|
||||
targetElementBoundingClientRect: DOMRectReadOnly | null = null
|
||||
targetElementBoundingClientRect: DOMRectReadOnly | null = null,
|
||||
): boolean {
|
||||
const elementBoundingClientRect =
|
||||
targetElementBoundingClientRect || targetElement.getBoundingClientRect();
|
||||
@ -180,7 +180,7 @@ class DomElementVisibilityService implements domElementVisibilityServiceInterfac
|
||||
elementRootNode instanceof ShadowRoot ? elementRootNode : targetElement.ownerDocument;
|
||||
const elementAtCenterPoint = rootElement.elementFromPoint(
|
||||
elementBoundingClientRect.left + elementBoundingClientRect.width / 2,
|
||||
elementBoundingClientRect.top + elementBoundingClientRect.height / 2
|
||||
elementBoundingClientRect.top + elementBoundingClientRect.height / 2,
|
||||
);
|
||||
|
||||
if (elementAtCenterPoint === targetElement) {
|
||||
|
@ -41,8 +41,8 @@ const initEventCount = Object.freeze(
|
||||
...eventCounts,
|
||||
[eventName]: 0,
|
||||
}),
|
||||
{}
|
||||
)
|
||||
{},
|
||||
),
|
||||
);
|
||||
|
||||
let confirmSpy: jest.SpyInstance<boolean, [message?: string]>;
|
||||
@ -68,7 +68,7 @@ describe("InsertAutofillContentService", () => {
|
||||
const autofillOverlayContentService = new AutofillOverlayContentService();
|
||||
const collectAutofillContentService = new CollectAutofillContentService(
|
||||
domElementVisibilityService,
|
||||
autofillOverlayContentService
|
||||
autofillOverlayContentService,
|
||||
);
|
||||
let insertAutofillContentService: InsertAutofillContentService;
|
||||
let fillScript: AutofillScript;
|
||||
@ -79,7 +79,7 @@ describe("InsertAutofillContentService", () => {
|
||||
windowSpy = jest.spyOn(window, "window", "get");
|
||||
insertAutofillContentService = new InsertAutofillContentService(
|
||||
domElementVisibilityService,
|
||||
collectAutofillContentService
|
||||
collectAutofillContentService,
|
||||
);
|
||||
fillScript = {
|
||||
script: [
|
||||
@ -117,10 +117,10 @@ describe("InsertAutofillContentService", () => {
|
||||
|
||||
expect(insertAutofillContentService["fillingWithinSandboxedIframe"]).not.toHaveBeenCalled();
|
||||
expect(
|
||||
insertAutofillContentService["userCancelledInsecureUrlAutofill"]
|
||||
insertAutofillContentService["userCancelledInsecureUrlAutofill"],
|
||||
).not.toHaveBeenCalled();
|
||||
expect(
|
||||
insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
|
||||
insertAutofillContentService["userCancelledUntrustedIframeAutofill"],
|
||||
).not.toHaveBeenCalled();
|
||||
expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled();
|
||||
});
|
||||
@ -137,10 +137,10 @@ describe("InsertAutofillContentService", () => {
|
||||
|
||||
expect(insertAutofillContentService["fillingWithinSandboxedIframe"]).toHaveBeenCalled();
|
||||
expect(
|
||||
insertAutofillContentService["userCancelledInsecureUrlAutofill"]
|
||||
insertAutofillContentService["userCancelledInsecureUrlAutofill"],
|
||||
).not.toHaveBeenCalled();
|
||||
expect(
|
||||
insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
|
||||
insertAutofillContentService["userCancelledUntrustedIframeAutofill"],
|
||||
).not.toHaveBeenCalled();
|
||||
expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled();
|
||||
});
|
||||
@ -160,7 +160,7 @@ describe("InsertAutofillContentService", () => {
|
||||
expect(insertAutofillContentService["fillingWithinSandboxedIframe"]).toHaveBeenCalled();
|
||||
expect(insertAutofillContentService["userCancelledInsecureUrlAutofill"]).toHaveBeenCalled();
|
||||
expect(
|
||||
insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
|
||||
insertAutofillContentService["userCancelledUntrustedIframeAutofill"],
|
||||
).not.toHaveBeenCalled();
|
||||
expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled();
|
||||
});
|
||||
@ -182,7 +182,7 @@ describe("InsertAutofillContentService", () => {
|
||||
expect(insertAutofillContentService["fillingWithinSandboxedIframe"]).toHaveBeenCalled();
|
||||
expect(insertAutofillContentService["userCancelledInsecureUrlAutofill"]).toHaveBeenCalled();
|
||||
expect(
|
||||
insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
|
||||
insertAutofillContentService["userCancelledUntrustedIframeAutofill"],
|
||||
).toHaveBeenCalled();
|
||||
expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled();
|
||||
});
|
||||
@ -204,26 +204,26 @@ describe("InsertAutofillContentService", () => {
|
||||
expect(insertAutofillContentService["fillingWithinSandboxedIframe"]).toHaveBeenCalled();
|
||||
expect(insertAutofillContentService["userCancelledInsecureUrlAutofill"]).toHaveBeenCalled();
|
||||
expect(
|
||||
insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
|
||||
insertAutofillContentService["userCancelledUntrustedIframeAutofill"],
|
||||
).toHaveBeenCalled();
|
||||
expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenCalledTimes(3);
|
||||
expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
fillScript.script[0],
|
||||
0,
|
||||
fillScript.script
|
||||
fillScript.script,
|
||||
);
|
||||
expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
fillScript.script[1],
|
||||
1,
|
||||
fillScript.script
|
||||
fillScript.script,
|
||||
);
|
||||
expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenNthCalledWith(
|
||||
3,
|
||||
fillScript.script[2],
|
||||
2,
|
||||
fillScript.script
|
||||
fillScript.script,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -432,7 +432,7 @@ describe("InsertAutofillContentService", () => {
|
||||
jest.advanceTimersByTime(20);
|
||||
|
||||
expect(
|
||||
insertAutofillContentService["autofillInsertActions"][action]
|
||||
insertAutofillContentService["autofillInsertActions"][action],
|
||||
).toHaveBeenCalledWith({
|
||||
opid,
|
||||
value,
|
||||
@ -451,18 +451,18 @@ describe("InsertAutofillContentService", () => {
|
||||
textInput.value = value;
|
||||
jest.spyOn(
|
||||
insertAutofillContentService["collectAutofillContentService"],
|
||||
"getAutofillFieldElementByOpid"
|
||||
"getAutofillFieldElementByOpid",
|
||||
);
|
||||
jest.spyOn(insertAutofillContentService as any, "insertValueIntoField");
|
||||
|
||||
insertAutofillContentService["handleFillFieldByOpidAction"](opid, value);
|
||||
|
||||
expect(
|
||||
insertAutofillContentService["collectAutofillContentService"].getAutofillFieldElementByOpid
|
||||
insertAutofillContentService["collectAutofillContentService"].getAutofillFieldElementByOpid,
|
||||
).toHaveBeenCalledWith(opid);
|
||||
expect(insertAutofillContentService["insertValueIntoField"]).toHaveBeenCalledWith(
|
||||
textInput,
|
||||
value
|
||||
value,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -483,17 +483,17 @@ describe("InsertAutofillContentService", () => {
|
||||
textInput.addEventListener("click", clickEventHandler);
|
||||
jest.spyOn(
|
||||
insertAutofillContentService["collectAutofillContentService"],
|
||||
"getAutofillFieldElementByOpid"
|
||||
"getAutofillFieldElementByOpid",
|
||||
);
|
||||
jest.spyOn(insertAutofillContentService as any, "triggerClickOnElement");
|
||||
|
||||
insertAutofillContentService["handleClickOnFieldByOpidAction"]("__1");
|
||||
|
||||
expect(
|
||||
insertAutofillContentService["collectAutofillContentService"].getAutofillFieldElementByOpid
|
||||
insertAutofillContentService["collectAutofillContentService"].getAutofillFieldElementByOpid,
|
||||
).toBeCalledWith("__1");
|
||||
expect((insertAutofillContentService as any)["triggerClickOnElement"]).toHaveBeenCalledWith(
|
||||
textInput
|
||||
textInput,
|
||||
);
|
||||
expect(clickEventCount).toBe(expectedClickEventCount);
|
||||
|
||||
@ -544,20 +544,20 @@ describe("InsertAutofillContentService", () => {
|
||||
});
|
||||
jest.spyOn(
|
||||
insertAutofillContentService["collectAutofillContentService"],
|
||||
"getAutofillFieldElementByOpid"
|
||||
"getAutofillFieldElementByOpid",
|
||||
);
|
||||
jest.spyOn(
|
||||
insertAutofillContentService as any,
|
||||
"simulateUserMouseClickAndFocusEventInteractions"
|
||||
"simulateUserMouseClickAndFocusEventInteractions",
|
||||
);
|
||||
|
||||
insertAutofillContentService["handleFocusOnFieldByOpidAction"]("__0");
|
||||
|
||||
expect(
|
||||
insertAutofillContentService["collectAutofillContentService"].getAutofillFieldElementByOpid
|
||||
insertAutofillContentService["collectAutofillContentService"].getAutofillFieldElementByOpid,
|
||||
).toBeCalledWith("__0");
|
||||
expect(
|
||||
insertAutofillContentService["simulateUserMouseClickAndFocusEventInteractions"]
|
||||
insertAutofillContentService["simulateUserMouseClickAndFocusEventInteractions"],
|
||||
).toHaveBeenCalledWith(targetInput, true);
|
||||
expect(elementEventCount).toEqual(expectedElementEventCount);
|
||||
});
|
||||
@ -572,7 +572,7 @@ describe("InsertAutofillContentService", () => {
|
||||
insertAutofillContentService["insertValueIntoField"](element, value);
|
||||
|
||||
expect(
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"]
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"],
|
||||
).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -584,7 +584,7 @@ describe("InsertAutofillContentService", () => {
|
||||
insertAutofillContentService["insertValueIntoField"](element, value);
|
||||
|
||||
expect(
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"]
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"],
|
||||
).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -598,7 +598,7 @@ describe("InsertAutofillContentService", () => {
|
||||
|
||||
expect(element.innerText).toBe(value);
|
||||
expect(
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"]
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"],
|
||||
).toHaveBeenCalledWith(element, expect.any(Function));
|
||||
});
|
||||
|
||||
@ -616,10 +616,10 @@ describe("InsertAutofillContentService", () => {
|
||||
expect(checkboxElement.checked).toBe(true);
|
||||
expect(radioElement.checked).toBe(true);
|
||||
expect(
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"]
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"],
|
||||
).toHaveBeenCalledWith(checkboxElement, expect.any(Function));
|
||||
expect(
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"]
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"],
|
||||
).toHaveBeenCalledWith(radioElement, expect.any(Function));
|
||||
|
||||
checkboxElement.checked = false;
|
||||
@ -641,14 +641,14 @@ describe("InsertAutofillContentService", () => {
|
||||
|
||||
expect(textInputElement.value).toBe(value1);
|
||||
expect(
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"]
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"],
|
||||
).toHaveBeenCalledWith(textInputElement, expect.any(Function));
|
||||
|
||||
insertAutofillContentService["insertValueIntoField"](textareaElement, value2);
|
||||
|
||||
expect(textareaElement.value).toBe(value2);
|
||||
expect(
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"]
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"],
|
||||
).toHaveBeenCalledWith(textareaElement, expect.any(Function));
|
||||
});
|
||||
});
|
||||
@ -661,23 +661,23 @@ describe("InsertAutofillContentService", () => {
|
||||
jest.spyOn(insertAutofillContentService as any, "triggerPostInsertEventsOnElement");
|
||||
jest.spyOn(insertAutofillContentService as any, "triggerFillAnimationOnElement");
|
||||
const valueChangeCallback = jest.fn(
|
||||
() => ((element as FillableFormFieldElement).value = value)
|
||||
() => ((element as FillableFormFieldElement).value = value),
|
||||
);
|
||||
|
||||
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"](
|
||||
element,
|
||||
valueChangeCallback
|
||||
valueChangeCallback,
|
||||
);
|
||||
|
||||
expect(insertAutofillContentService["triggerPreInsertEventsOnElement"]).toHaveBeenCalledWith(
|
||||
element
|
||||
element,
|
||||
);
|
||||
expect(valueChangeCallback).toHaveBeenCalled();
|
||||
expect(insertAutofillContentService["triggerPostInsertEventsOnElement"]).toHaveBeenCalledWith(
|
||||
element
|
||||
element,
|
||||
);
|
||||
expect(insertAutofillContentService["triggerFillAnimationOnElement"]).toHaveBeenCalledWith(
|
||||
element
|
||||
element,
|
||||
);
|
||||
expect((element as FillableFormFieldElement).value).toBe(value);
|
||||
});
|
||||
@ -690,17 +690,17 @@ describe("InsertAutofillContentService", () => {
|
||||
const element = document.getElementById("username") as FillableFormFieldElement;
|
||||
jest.spyOn(
|
||||
insertAutofillContentService as any,
|
||||
"simulateUserMouseClickAndFocusEventInteractions"
|
||||
"simulateUserMouseClickAndFocusEventInteractions",
|
||||
);
|
||||
jest.spyOn(insertAutofillContentService as any, "simulateUserKeyboardEventInteractions");
|
||||
|
||||
insertAutofillContentService["triggerPreInsertEventsOnElement"](element);
|
||||
|
||||
expect(
|
||||
insertAutofillContentService["simulateUserMouseClickAndFocusEventInteractions"]
|
||||
insertAutofillContentService["simulateUserMouseClickAndFocusEventInteractions"],
|
||||
).toHaveBeenCalledWith(element);
|
||||
expect(
|
||||
insertAutofillContentService["simulateUserKeyboardEventInteractions"]
|
||||
insertAutofillContentService["simulateUserKeyboardEventInteractions"],
|
||||
).toHaveBeenCalledWith(element);
|
||||
expect(element.value).toBe(initialElementValue);
|
||||
});
|
||||
@ -718,10 +718,10 @@ describe("InsertAutofillContentService", () => {
|
||||
insertAutofillContentService["triggerPostInsertEventsOnElement"](element);
|
||||
|
||||
expect(
|
||||
insertAutofillContentService["simulateUserKeyboardEventInteractions"]
|
||||
insertAutofillContentService["simulateUserKeyboardEventInteractions"],
|
||||
).toHaveBeenCalledWith(element);
|
||||
expect(insertAutofillContentService["simulateInputElementChangedEvent"]).toHaveBeenCalledWith(
|
||||
element
|
||||
element,
|
||||
);
|
||||
expect(element.blur).toHaveBeenCalled();
|
||||
expect(element.value).toBe(elementValue);
|
||||
@ -738,7 +738,7 @@ describe("InsertAutofillContentService", () => {
|
||||
it("the element is a non-hidden hidden input type", async () => {
|
||||
document.body.innerHTML = mockLoginForm + '<input type="hidden" />';
|
||||
const testElement = document.querySelector(
|
||||
'input[type="hidden"]'
|
||||
'input[type="hidden"]',
|
||||
) as FillableFormFieldElement;
|
||||
jest.spyOn(testElement.classList, "add");
|
||||
jest.spyOn(testElement.classList, "remove");
|
||||
@ -778,7 +778,7 @@ describe("InsertAutofillContentService", () => {
|
||||
|
||||
it("the element has a `visibility: hidden;` CSS rule applied to it", () => {
|
||||
const testElement = document.querySelector(
|
||||
'input[type="password"]'
|
||||
'input[type="password"]',
|
||||
) as FillableFormFieldElement;
|
||||
testElement.style.visibility = "hidden";
|
||||
jest.spyOn(testElement.classList, "add");
|
||||
@ -793,7 +793,7 @@ describe("InsertAutofillContentService", () => {
|
||||
|
||||
it("the element has a `display: none;` CSS rule applied to it", () => {
|
||||
const testElement = document.querySelector(
|
||||
'input[type="password"]'
|
||||
'input[type="password"]',
|
||||
) as FillableFormFieldElement;
|
||||
testElement.style.display = "none";
|
||||
jest.spyOn(testElement.classList, "add");
|
||||
@ -810,7 +810,7 @@ describe("InsertAutofillContentService", () => {
|
||||
document.body.innerHTML =
|
||||
mockLoginForm + '<div style="opacity: 0;"><input type="email" /></div>';
|
||||
const testElement = document.querySelector(
|
||||
'input[type="email"]'
|
||||
'input[type="email"]',
|
||||
) as FillableFormFieldElement;
|
||||
jest.spyOn(testElement.classList, "add");
|
||||
jest.spyOn(testElement.classList, "remove");
|
||||
@ -826,11 +826,11 @@ describe("InsertAutofillContentService", () => {
|
||||
describe("will trigger the animation when...", () => {
|
||||
it("the element is a non-hidden password field", () => {
|
||||
const testElement = document.querySelector(
|
||||
'input[type="password"]'
|
||||
'input[type="password"]',
|
||||
) as FillableFormFieldElement;
|
||||
jest.spyOn(
|
||||
insertAutofillContentService["domElementVisibilityService"],
|
||||
"isElementHiddenByCss"
|
||||
"isElementHiddenByCss",
|
||||
);
|
||||
jest.spyOn(testElement.classList, "add");
|
||||
jest.spyOn(testElement.classList, "remove");
|
||||
@ -839,20 +839,20 @@ describe("InsertAutofillContentService", () => {
|
||||
jest.advanceTimersByTime(200);
|
||||
|
||||
expect(
|
||||
insertAutofillContentService["domElementVisibilityService"].isElementHiddenByCss
|
||||
insertAutofillContentService["domElementVisibilityService"].isElementHiddenByCss,
|
||||
).toHaveBeenCalledWith(testElement);
|
||||
expect(testElement.classList.add).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
expect(testElement.classList.remove).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
});
|
||||
|
||||
it("the element is a non-hidden email input", () => {
|
||||
document.body.innerHTML = mockLoginForm + '<input type="email" />';
|
||||
const testElement = document.querySelector(
|
||||
'input[type="email"]'
|
||||
'input[type="email"]',
|
||||
) as FillableFormFieldElement;
|
||||
jest.spyOn(testElement.classList, "add");
|
||||
jest.spyOn(testElement.classList, "remove");
|
||||
@ -861,17 +861,17 @@ describe("InsertAutofillContentService", () => {
|
||||
jest.advanceTimersByTime(200);
|
||||
|
||||
expect(testElement.classList.add).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
expect(testElement.classList.remove).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
});
|
||||
|
||||
it("the element is a non-hidden text input", () => {
|
||||
document.body.innerHTML = mockLoginForm + '<input type="text" />';
|
||||
const testElement = document.querySelector(
|
||||
'input[type="text"]'
|
||||
'input[type="text"]',
|
||||
) as FillableFormFieldElement;
|
||||
jest.spyOn(testElement.classList, "add");
|
||||
jest.spyOn(testElement.classList, "remove");
|
||||
@ -880,17 +880,17 @@ describe("InsertAutofillContentService", () => {
|
||||
jest.advanceTimersByTime(200);
|
||||
|
||||
expect(testElement.classList.add).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
expect(testElement.classList.remove).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
});
|
||||
|
||||
it("the element is a non-hidden number input", () => {
|
||||
document.body.innerHTML = mockLoginForm + '<input type="number" />';
|
||||
const testElement = document.querySelector(
|
||||
'input[type="number"]'
|
||||
'input[type="number"]',
|
||||
) as FillableFormFieldElement;
|
||||
jest.spyOn(testElement.classList, "add");
|
||||
jest.spyOn(testElement.classList, "remove");
|
||||
@ -899,10 +899,10 @@ describe("InsertAutofillContentService", () => {
|
||||
jest.advanceTimersByTime(200);
|
||||
|
||||
expect(testElement.classList.add).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
expect(testElement.classList.remove).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
});
|
||||
|
||||
@ -916,10 +916,10 @@ describe("InsertAutofillContentService", () => {
|
||||
jest.advanceTimersByTime(200);
|
||||
|
||||
expect(testElement.classList.add).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
expect(testElement.classList.remove).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
});
|
||||
|
||||
@ -933,10 +933,10 @@ describe("InsertAutofillContentService", () => {
|
||||
jest.advanceTimersByTime(200);
|
||||
|
||||
expect(testElement.classList.add).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
expect(testElement.classList.remove).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
});
|
||||
|
||||
@ -950,10 +950,10 @@ describe("InsertAutofillContentService", () => {
|
||||
jest.advanceTimersByTime(200);
|
||||
|
||||
expect(testElement.classList.add).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
expect(testElement.classList.remove).toHaveBeenCalledWith(
|
||||
"com-bitwarden-browser-animated-fill"
|
||||
"com-bitwarden-browser-animated-fill",
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1009,11 +1009,11 @@ describe("InsertAutofillContentService", () => {
|
||||
insertAutofillContentService["simulateUserMouseClickAndFocusEventInteractions"](inputElement);
|
||||
|
||||
expect(insertAutofillContentService["triggerClickOnElement"]).toHaveBeenCalledWith(
|
||||
inputElement
|
||||
inputElement,
|
||||
);
|
||||
expect(insertAutofillContentService["triggerFocusOnElement"]).toHaveBeenCalledWith(
|
||||
inputElement,
|
||||
false
|
||||
false,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1027,7 +1027,7 @@ describe("InsertAutofillContentService", () => {
|
||||
|
||||
[EVENTS.KEYDOWN, EVENTS.KEYPRESS, EVENTS.KEYUP].forEach((eventName) => {
|
||||
expect(inputElement.dispatchEvent).toHaveBeenCalledWith(
|
||||
new KeyboardEvent(eventName, { bubbles: true })
|
||||
new KeyboardEvent(eventName, { bubbles: true }),
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1042,7 +1042,7 @@ describe("InsertAutofillContentService", () => {
|
||||
|
||||
[EVENTS.INPUT, EVENTS.CHANGE].forEach((eventName) => {
|
||||
expect(inputElement.dispatchEvent).toHaveBeenCalledWith(
|
||||
new Event(eventName, { bubbles: true })
|
||||
new Event(eventName, { bubbles: true }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -21,7 +21,7 @@ class InsertAutofillContentService implements InsertAutofillContentServiceInterf
|
||||
*/
|
||||
constructor(
|
||||
domElementVisibilityService: DomElementVisibilityService,
|
||||
collectAutofillContentService: CollectAutofillContentService
|
||||
collectAutofillContentService: CollectAutofillContentService,
|
||||
) {
|
||||
this.domElementVisibilityService = domElementVisibilityService;
|
||||
this.collectAutofillContentService = collectAutofillContentService;
|
||||
@ -97,8 +97,8 @@ class InsertAutofillContentService implements InsertAutofillContentServiceInterf
|
||||
this.collectAutofillContentService.queryAllTreeWalkerNodes(
|
||||
document.documentElement,
|
||||
(node: Node) => node instanceof HTMLInputElement && node.type === "password",
|
||||
false
|
||||
)?.length
|
||||
false,
|
||||
)?.length,
|
||||
);
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@ class InsertAutofillContentService implements InsertAutofillContentServiceInterf
|
||||
*/
|
||||
private runFillScriptAction = (
|
||||
[action, opid, value]: FillScript,
|
||||
actionIndex: number
|
||||
actionIndex: number,
|
||||
): Promise<void> => {
|
||||
if (!opid || !this.autofillInsertActions[action]) {
|
||||
return;
|
||||
@ -150,7 +150,7 @@ class InsertAutofillContentService implements InsertAutofillContentServiceInterf
|
||||
setTimeout(() => {
|
||||
this.autofillInsertActions[action]({ opid, value });
|
||||
resolve();
|
||||
}, delayActionsInMilliseconds * actionIndex)
|
||||
}, delayActionsInMilliseconds * actionIndex),
|
||||
);
|
||||
};
|
||||
|
||||
@ -233,7 +233,7 @@ class InsertAutofillContentService implements InsertAutofillContentServiceInterf
|
||||
*/
|
||||
private handleInsertValueAndTriggerSimulatedEvents(
|
||||
element: FormFieldElement,
|
||||
valueChangeCallback: CallableFunction
|
||||
valueChangeCallback: CallableFunction,
|
||||
): void {
|
||||
this.triggerPreInsertEventsOnElement(element);
|
||||
valueChangeCallback();
|
||||
@ -341,7 +341,7 @@ class InsertAutofillContentService implements InsertAutofillContentServiceInterf
|
||||
*/
|
||||
private simulateUserMouseClickAndFocusEventInteractions(
|
||||
element: FormFieldElement,
|
||||
shouldResetValue = false
|
||||
shouldResetValue = false,
|
||||
): void {
|
||||
this.triggerClickOnElement(element);
|
||||
this.triggerFocusOnElement(element, shouldResetValue);
|
||||
|
@ -52,7 +52,7 @@ describe("setElementStyles", () => {
|
||||
const domParser = new DOMParser();
|
||||
const testDivDOM = domParser.parseFromString(
|
||||
"<div>This is an unexciting div.</div>",
|
||||
"text/html"
|
||||
"text/html",
|
||||
);
|
||||
const testDiv = testDivDOM.querySelector("div");
|
||||
|
||||
@ -67,7 +67,7 @@ describe("setElementStyles", () => {
|
||||
const domParser = new DOMParser();
|
||||
const testDivDOM = domParser.parseFromString(
|
||||
"<div>This is an unexciting div.</div>",
|
||||
"text/html"
|
||||
"text/html",
|
||||
);
|
||||
const testDiv = testDivDOM.querySelector("div");
|
||||
|
||||
@ -82,7 +82,7 @@ describe("setElementStyles", () => {
|
||||
const domParser = new DOMParser();
|
||||
const testDivDOM = domParser.parseFromString(
|
||||
"<div>This is an unexciting div.</div>",
|
||||
"text/html"
|
||||
"text/html",
|
||||
);
|
||||
const testDiv = testDivDOM.querySelector("div");
|
||||
|
||||
@ -101,7 +101,7 @@ describe("setElementStyles", () => {
|
||||
const domParser = new DOMParser();
|
||||
const testDivDOM = domParser.parseFromString(
|
||||
"<div>This is an unexciting div.</div>",
|
||||
"text/html"
|
||||
"text/html",
|
||||
);
|
||||
const testDiv = testDivDOM.querySelector("div");
|
||||
|
||||
|
@ -65,7 +65,7 @@ function buildSvgDomElement(svgString: string, ariaHidden = true): HTMLElement {
|
||||
*/
|
||||
async function sendExtensionMessage(
|
||||
command: string,
|
||||
options: Record<string, any> = {}
|
||||
options: Record<string, any> = {},
|
||||
): Promise<any | void> {
|
||||
return new Promise((resolve) => {
|
||||
chrome.runtime.sendMessage(Object.assign({ command }, options), (response) => {
|
||||
@ -88,7 +88,7 @@ async function sendExtensionMessage(
|
||||
function setElementStyles(
|
||||
element: HTMLElement,
|
||||
styles: Partial<CSSStyleDeclaration>,
|
||||
priority?: boolean
|
||||
priority?: boolean,
|
||||
) {
|
||||
if (!element || !styles || !Object.keys(styles).length) {
|
||||
return;
|
||||
@ -98,7 +98,7 @@ function setElementStyles(
|
||||
element.style.setProperty(
|
||||
styleProperty.replace(/([a-z])([A-Z])/g, "$1-$2"), // Convert camelCase to kebab-case
|
||||
styles[styleProperty],
|
||||
priority ? "important" : undefined
|
||||
priority ? "important" : undefined,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ export default class CommandsBackground {
|
||||
private passwordGenerationService: PasswordGenerationServiceAbstraction,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private vaultTimeoutService: VaultTimeoutService,
|
||||
private authService: AuthService
|
||||
private authService: AuthService,
|
||||
) {
|
||||
this.isSafari = this.platformUtilsService.isSafari();
|
||||
this.isVivaldi = this.platformUtilsService.isVivaldi();
|
||||
@ -85,7 +85,7 @@ export default class CommandsBackground {
|
||||
await BrowserApi.tabSendMessageData(
|
||||
tab,
|
||||
"addToLockedVaultPendingNotifications",
|
||||
retryMessage
|
||||
retryMessage,
|
||||
);
|
||||
|
||||
await openUnlockPopout(tab);
|
||||
|
@ -14,7 +14,7 @@ export default class IdleBackground {
|
||||
constructor(
|
||||
private vaultTimeoutService: VaultTimeoutService,
|
||||
private stateService: BrowserStateService,
|
||||
private notificationsService: NotificationsService
|
||||
private notificationsService: NotificationsService,
|
||||
) {
|
||||
this.idle = chrome.idle || (browser != null ? browser.idle : null);
|
||||
}
|
||||
|
@ -284,17 +284,17 @@ export default class MainBackground {
|
||||
BrowserApi.manifestVersion === 3
|
||||
? new LocalBackedSessionStorageService(
|
||||
new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, false),
|
||||
new KeyGenerationService(this.cryptoFunctionService)
|
||||
new KeyGenerationService(this.cryptoFunctionService),
|
||||
)
|
||||
: new BackgroundMemoryStorageService();
|
||||
this.globalStateProvider = new DefaultGlobalStateProvider(
|
||||
this.memoryStorageService as BackgroundMemoryStorageService,
|
||||
this.storageService as BrowserLocalStorageService
|
||||
this.storageService as BrowserLocalStorageService,
|
||||
);
|
||||
this.accountService = new AccountServiceImplementation(
|
||||
this.messagingService,
|
||||
this.logService,
|
||||
this.globalStateProvider
|
||||
this.globalStateProvider,
|
||||
);
|
||||
this.stateService = new BrowserStateService(
|
||||
this.storageService,
|
||||
@ -302,7 +302,7 @@ export default class MainBackground {
|
||||
this.memoryStorageService,
|
||||
this.logService,
|
||||
new StateFactory(GlobalState, Account),
|
||||
this.accountService
|
||||
this.accountService,
|
||||
);
|
||||
this.platformUtilsService = new BrowserPlatformUtilsService(
|
||||
this.messagingService,
|
||||
@ -324,14 +324,14 @@ export default class MainBackground {
|
||||
return promise.then((result) => result.response === "unlocked");
|
||||
}
|
||||
},
|
||||
window
|
||||
window,
|
||||
);
|
||||
this.i18nService = new BrowserI18nService(BrowserApi.getUILanguage(), this.stateService);
|
||||
this.encryptService = flagEnabled("multithreadDecryption")
|
||||
? new MultithreadEncryptServiceImplementation(
|
||||
this.cryptoFunctionService,
|
||||
this.logService,
|
||||
true
|
||||
true,
|
||||
)
|
||||
: new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, true);
|
||||
this.cryptoService = new BrowserCryptoService(
|
||||
@ -339,7 +339,7 @@ export default class MainBackground {
|
||||
this.encryptService,
|
||||
this.platformUtilsService,
|
||||
this.logService,
|
||||
this.stateService
|
||||
this.stateService,
|
||||
);
|
||||
this.tokenService = new TokenService(this.stateService);
|
||||
this.appIdService = new AppIdService(this.storageService);
|
||||
@ -349,20 +349,20 @@ export default class MainBackground {
|
||||
this.platformUtilsService,
|
||||
this.environmentService,
|
||||
this.appIdService,
|
||||
(expired: boolean) => this.logout(expired)
|
||||
(expired: boolean) => this.logout(expired),
|
||||
);
|
||||
this.settingsService = new BrowserSettingsService(this.stateService);
|
||||
this.fileUploadService = new FileUploadService(this.logService);
|
||||
this.cipherFileUploadService = new CipherFileUploadService(
|
||||
this.apiService,
|
||||
this.fileUploadService
|
||||
this.fileUploadService,
|
||||
);
|
||||
this.searchService = new SearchService(this.logService, this.i18nService);
|
||||
|
||||
this.collectionService = new CollectionService(
|
||||
this.cryptoService,
|
||||
this.i18nService,
|
||||
this.stateService
|
||||
this.stateService,
|
||||
);
|
||||
this.syncNotifierService = new SyncNotifierService();
|
||||
this.organizationService = new BrowserOrganizationService(this.stateService);
|
||||
@ -370,7 +370,7 @@ export default class MainBackground {
|
||||
this.policyApiService = new PolicyApiService(
|
||||
this.policyService,
|
||||
this.apiService,
|
||||
this.stateService
|
||||
this.stateService,
|
||||
);
|
||||
this.keyConnectorService = new KeyConnectorService(
|
||||
this.stateService,
|
||||
@ -380,7 +380,7 @@ export default class MainBackground {
|
||||
this.logService,
|
||||
this.organizationService,
|
||||
this.cryptoFunctionService,
|
||||
logoutCallback
|
||||
logoutCallback,
|
||||
);
|
||||
|
||||
this.passwordStrengthService = new PasswordStrengthService();
|
||||
@ -388,7 +388,7 @@ export default class MainBackground {
|
||||
this.passwordGenerationService = new PasswordGenerationService(
|
||||
this.cryptoService,
|
||||
this.policyService,
|
||||
this.stateService
|
||||
this.stateService,
|
||||
);
|
||||
|
||||
this.twoFactorService = new TwoFactorService(this.i18nService, this.platformUtilsService);
|
||||
@ -412,7 +412,7 @@ export default class MainBackground {
|
||||
this.appIdService,
|
||||
this.devicesApiService,
|
||||
this.i18nService,
|
||||
this.platformUtilsService
|
||||
this.platformUtilsService,
|
||||
);
|
||||
|
||||
this.devicesService = new DevicesServiceImplementation(this.devicesApiService);
|
||||
@ -436,7 +436,7 @@ export default class MainBackground {
|
||||
this.passwordStrengthService,
|
||||
this.policyService,
|
||||
this.deviceTrustCryptoService,
|
||||
this.authRequestCryptoService
|
||||
this.authRequestCryptoService,
|
||||
);
|
||||
|
||||
this.userVerificationApiService = new UserVerificationApiService(this.apiService);
|
||||
@ -445,7 +445,7 @@ export default class MainBackground {
|
||||
this.stateService,
|
||||
this.cryptoService,
|
||||
this.i18nService,
|
||||
this.userVerificationApiService
|
||||
this.userVerificationApiService,
|
||||
);
|
||||
|
||||
this.configApiService = new ConfigApiService(this.apiService, this.authService);
|
||||
@ -456,7 +456,7 @@ export default class MainBackground {
|
||||
this.authService,
|
||||
this.environmentService,
|
||||
this.logService,
|
||||
true
|
||||
true,
|
||||
);
|
||||
|
||||
this.cipherService = new CipherService(
|
||||
@ -468,13 +468,13 @@ export default class MainBackground {
|
||||
this.stateService,
|
||||
this.encryptService,
|
||||
this.cipherFileUploadService,
|
||||
this.configService
|
||||
this.configService,
|
||||
);
|
||||
this.folderService = new BrowserFolderService(
|
||||
this.cryptoService,
|
||||
this.i18nService,
|
||||
this.cipherService,
|
||||
this.stateService
|
||||
this.stateService,
|
||||
);
|
||||
this.folderApiService = new FolderApiService(this.folderService, this.apiService);
|
||||
|
||||
@ -483,7 +483,7 @@ export default class MainBackground {
|
||||
this.tokenService,
|
||||
this.policyService,
|
||||
this.stateService,
|
||||
this.userVerificationService
|
||||
this.userVerificationService,
|
||||
);
|
||||
|
||||
this.vaultFilterService = new VaultFilterService(
|
||||
@ -492,7 +492,7 @@ export default class MainBackground {
|
||||
this.folderService,
|
||||
this.cipherService,
|
||||
this.collectionService,
|
||||
this.policyService
|
||||
this.policyService,
|
||||
);
|
||||
|
||||
this.vaultTimeoutService = new VaultTimeoutService(
|
||||
@ -507,19 +507,19 @@ export default class MainBackground {
|
||||
this.authService,
|
||||
this.vaultTimeoutSettingsService,
|
||||
lockedCallback,
|
||||
logoutCallback
|
||||
logoutCallback,
|
||||
);
|
||||
this.containerService = new ContainerService(this.cryptoService, this.encryptService);
|
||||
this.sendService = new BrowserSendService(
|
||||
this.cryptoService,
|
||||
this.i18nService,
|
||||
this.cryptoFunctionService,
|
||||
this.stateService
|
||||
this.stateService,
|
||||
);
|
||||
this.sendApiService = new SendApiService(
|
||||
this.apiService,
|
||||
this.fileUploadService,
|
||||
this.sendService
|
||||
this.sendService,
|
||||
);
|
||||
this.providerService = new ProviderService(this.stateService);
|
||||
this.syncService = new SyncService(
|
||||
@ -539,18 +539,18 @@ export default class MainBackground {
|
||||
this.folderApiService,
|
||||
this.organizationService,
|
||||
this.sendApiService,
|
||||
logoutCallback
|
||||
logoutCallback,
|
||||
);
|
||||
this.eventUploadService = new EventUploadService(
|
||||
this.apiService,
|
||||
this.stateService,
|
||||
this.logService
|
||||
this.logService,
|
||||
);
|
||||
this.eventCollectionService = new EventCollectionService(
|
||||
this.cipherService,
|
||||
this.stateService,
|
||||
this.organizationService,
|
||||
this.eventUploadService
|
||||
this.eventUploadService,
|
||||
);
|
||||
this.totpService = new TotpService(this.cryptoFunctionService, this.logService);
|
||||
|
||||
@ -561,7 +561,7 @@ export default class MainBackground {
|
||||
this.eventCollectionService,
|
||||
this.logService,
|
||||
this.settingsService,
|
||||
this.userVerificationService
|
||||
this.userVerificationService,
|
||||
);
|
||||
this.auditService = new AuditService(this.cryptoFunctionService, this.apiService);
|
||||
|
||||
@ -573,7 +573,7 @@ export default class MainBackground {
|
||||
this.importApiService,
|
||||
this.i18nService,
|
||||
this.collectionService,
|
||||
this.cryptoService
|
||||
this.cryptoService,
|
||||
);
|
||||
|
||||
this.exportService = new VaultExportService(
|
||||
@ -582,7 +582,7 @@ export default class MainBackground {
|
||||
this.apiService,
|
||||
this.cryptoService,
|
||||
this.cryptoFunctionService,
|
||||
this.stateService
|
||||
this.stateService,
|
||||
);
|
||||
this.notificationsService = new NotificationsService(
|
||||
this.logService,
|
||||
@ -593,7 +593,7 @@ export default class MainBackground {
|
||||
logoutCallback,
|
||||
this.stateService,
|
||||
this.authService,
|
||||
this.messagingService
|
||||
this.messagingService,
|
||||
);
|
||||
|
||||
this.fido2UserInterfaceService = new BrowserFido2UserInterfaceService(this.authService);
|
||||
@ -601,14 +601,14 @@ export default class MainBackground {
|
||||
this.cipherService,
|
||||
this.fido2UserInterfaceService,
|
||||
this.syncService,
|
||||
this.logService
|
||||
this.logService,
|
||||
);
|
||||
this.fido2ClientService = new Fido2ClientService(
|
||||
this.fido2AuthenticatorService,
|
||||
this.configService,
|
||||
this.authService,
|
||||
this.stateService,
|
||||
this.logService
|
||||
this.logService,
|
||||
);
|
||||
|
||||
const systemUtilsServiceReloadCallback = () => {
|
||||
@ -624,7 +624,7 @@ export default class MainBackground {
|
||||
this.messagingService,
|
||||
this.platformUtilsService,
|
||||
systemUtilsServiceReloadCallback,
|
||||
this.stateService
|
||||
this.stateService,
|
||||
);
|
||||
|
||||
// Other fields
|
||||
@ -642,7 +642,7 @@ export default class MainBackground {
|
||||
this.environmentService,
|
||||
this.messagingService,
|
||||
this.logService,
|
||||
this.configService
|
||||
this.configService,
|
||||
);
|
||||
this.nativeMessagingBackground = new NativeMessagingBackground(
|
||||
this.cryptoService,
|
||||
@ -654,14 +654,14 @@ export default class MainBackground {
|
||||
this.platformUtilsService,
|
||||
this.stateService,
|
||||
this.logService,
|
||||
this.authService
|
||||
this.authService,
|
||||
);
|
||||
this.commandsBackground = new CommandsBackground(
|
||||
this,
|
||||
this.passwordGenerationService,
|
||||
this.platformUtilsService,
|
||||
this.vaultTimeoutService,
|
||||
this.authService
|
||||
this.authService,
|
||||
);
|
||||
this.notificationBackground = new NotificationBackground(
|
||||
this.autofillService,
|
||||
@ -670,7 +670,7 @@ export default class MainBackground {
|
||||
this.policyService,
|
||||
this.folderService,
|
||||
this.stateService,
|
||||
this.environmentService
|
||||
this.environmentService,
|
||||
);
|
||||
this.overlayBackground = new OverlayBackground(
|
||||
this.cipherService,
|
||||
@ -679,12 +679,12 @@ export default class MainBackground {
|
||||
this.environmentService,
|
||||
this.settingsService,
|
||||
this.stateService,
|
||||
this.i18nService
|
||||
this.i18nService,
|
||||
);
|
||||
this.tabsBackground = new TabsBackground(
|
||||
this,
|
||||
this.notificationBackground,
|
||||
this.overlayBackground
|
||||
this.overlayBackground,
|
||||
);
|
||||
if (!this.popupOnlyContext) {
|
||||
const contextMenuClickedHandler = new ContextMenuClickedHandler(
|
||||
@ -712,7 +712,7 @@ export default class MainBackground {
|
||||
this.stateService,
|
||||
this.totpService,
|
||||
this.eventCollectionService,
|
||||
this.userVerificationService
|
||||
this.userVerificationService,
|
||||
);
|
||||
|
||||
this.contextMenusBackground = new ContextMenusBackground(contextMenuClickedHandler);
|
||||
@ -721,18 +721,18 @@ export default class MainBackground {
|
||||
this.idleBackground = new IdleBackground(
|
||||
this.vaultTimeoutService,
|
||||
this.stateService,
|
||||
this.notificationsService
|
||||
this.notificationsService,
|
||||
);
|
||||
this.webRequestBackground = new WebRequestBackground(
|
||||
this.platformUtilsService,
|
||||
this.cipherService,
|
||||
this.authService
|
||||
this.authService,
|
||||
);
|
||||
|
||||
this.usernameGenerationService = new UsernameGenerationService(
|
||||
this.cryptoService,
|
||||
this.stateService,
|
||||
this.apiService
|
||||
this.apiService,
|
||||
);
|
||||
|
||||
this.avatarUpdateService = new AvatarUpdateService(this.apiService, this.stateService);
|
||||
@ -741,13 +741,13 @@ export default class MainBackground {
|
||||
this.mainContextMenuHandler = new MainContextMenuHandler(
|
||||
this.stateService,
|
||||
this.i18nService,
|
||||
this.logService
|
||||
this.logService,
|
||||
);
|
||||
|
||||
this.cipherContextMenuHandler = new CipherContextMenuHandler(
|
||||
this.mainContextMenuHandler,
|
||||
this.authService,
|
||||
this.cipherService
|
||||
this.cipherService,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -928,7 +928,7 @@ export default class MainBackground {
|
||||
tab: tab,
|
||||
sender: sender,
|
||||
},
|
||||
options
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ export class NativeMessagingBackground {
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private stateService: StateService,
|
||||
private logService: LogService,
|
||||
private authService: AuthService
|
||||
private authService: AuthService,
|
||||
) {
|
||||
this.stateService.setBiometricFingerprintValidated(false);
|
||||
|
||||
@ -136,7 +136,7 @@ export class NativeMessagingBackground {
|
||||
const decrypted = await this.cryptoFunctionService.rsaDecrypt(
|
||||
encrypted,
|
||||
this.privateKey,
|
||||
EncryptionAlgorithm
|
||||
EncryptionAlgorithm,
|
||||
);
|
||||
|
||||
if (this.validatingFingerprint) {
|
||||
@ -278,7 +278,7 @@ export class NativeMessagingBackground {
|
||||
let message = rawMessage as ReceiveMessage;
|
||||
if (!this.platformUtilsService.isSafari()) {
|
||||
message = JSON.parse(
|
||||
await this.cryptoService.decryptToUtf8(rawMessage as EncString, this.sharedSecret)
|
||||
await this.cryptoService.decryptToUtf8(rawMessage as EncString, this.sharedSecret),
|
||||
);
|
||||
}
|
||||
|
||||
@ -328,7 +328,7 @@ export class NativeMessagingBackground {
|
||||
try {
|
||||
if (message.userKeyB64) {
|
||||
const userKey = new SymmetricCryptoKey(
|
||||
Utils.fromB64ToArray(message.userKeyB64)
|
||||
Utils.fromB64ToArray(message.userKeyB64),
|
||||
) as UserKey;
|
||||
await this.cryptoService.setUserKey(userKey);
|
||||
} else if (message.keyB64) {
|
||||
@ -340,11 +340,11 @@ export class NativeMessagingBackground {
|
||||
throw new Error("No encrypted user key found");
|
||||
}
|
||||
const masterKey = new SymmetricCryptoKey(
|
||||
Utils.fromB64ToArray(message.keyB64)
|
||||
Utils.fromB64ToArray(message.keyB64),
|
||||
) as MasterKey;
|
||||
const userKey = await this.cryptoService.decryptUserKeyWithMasterKey(
|
||||
masterKey,
|
||||
new EncString(encUserKey)
|
||||
new EncString(encUserKey),
|
||||
);
|
||||
await this.cryptoService.setMasterKey(masterKey);
|
||||
await this.cryptoService.setUserKey(userKey);
|
||||
@ -424,7 +424,7 @@ export class NativeMessagingBackground {
|
||||
private async showFingerprintDialog() {
|
||||
const fingerprint = await this.cryptoService.getFingerprint(
|
||||
await this.stateService.getUserId(),
|
||||
this.publicKey
|
||||
this.publicKey,
|
||||
);
|
||||
|
||||
this.messagingService.send("showNativeMessagingFinterprintDialog", {
|
||||
|
@ -41,7 +41,7 @@ export default class RuntimeBackground {
|
||||
private environmentService: BrowserEnvironmentService,
|
||||
private messagingService: MessagingService,
|
||||
private logService: LogService,
|
||||
private configService: ConfigServiceAbstraction
|
||||
private configService: ConfigServiceAbstraction,
|
||||
) {
|
||||
// onInstalled listener must be wired up before anything else, so we do it in the ctor
|
||||
chrome.runtime.onInstalled.addListener((details: any) => {
|
||||
@ -58,7 +58,7 @@ export default class RuntimeBackground {
|
||||
const backgroundMessageListener = (
|
||||
msg: any,
|
||||
sender: chrome.runtime.MessageSender,
|
||||
sendResponse: any
|
||||
sendResponse: any,
|
||||
) => {
|
||||
const messagesWithResponse = [
|
||||
"checkFido2FeatureEnabled",
|
||||
@ -69,7 +69,7 @@ export default class RuntimeBackground {
|
||||
if (messagesWithResponse.includes(msg.command)) {
|
||||
this.processMessage(msg, sender).then(
|
||||
(value) => sendResponse({ result: value }),
|
||||
(error) => sendResponse({ error: { ...error, message: error.message } })
|
||||
(error) => sendResponse({ error: { ...error, message: error.message } }),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
@ -106,7 +106,7 @@ export default class RuntimeBackground {
|
||||
await BrowserApi.tabSendMessageData(
|
||||
item.commandToRetry.sender.tab,
|
||||
"unlockCompleted",
|
||||
item
|
||||
item,
|
||||
);
|
||||
}
|
||||
break;
|
||||
@ -134,7 +134,7 @@ export default class RuntimeBackground {
|
||||
await this.autofillService.injectAutofillScripts(
|
||||
sender,
|
||||
await this.configService.getFeatureFlag<boolean>(FeatureFlag.AutofillV2),
|
||||
await this.configService.getFeatureFlag<boolean>(FeatureFlag.AutofillOverlay)
|
||||
await this.configService.getFeatureFlag<boolean>(FeatureFlag.AutofillOverlay),
|
||||
);
|
||||
break;
|
||||
case "bgCollectPageDetails":
|
||||
@ -163,7 +163,7 @@ export default class RuntimeBackground {
|
||||
details: msg.details,
|
||||
},
|
||||
],
|
||||
msg.sender === "autofill_cmd"
|
||||
msg.sender === "autofill_cmd",
|
||||
);
|
||||
if (totpCode != null) {
|
||||
this.platformUtilsService.copyToClipboard(totpCode, { window: window });
|
||||
@ -180,7 +180,7 @@ export default class RuntimeBackground {
|
||||
},
|
||||
],
|
||||
false,
|
||||
CipherType.Card
|
||||
CipherType.Card,
|
||||
);
|
||||
break;
|
||||
}
|
||||
@ -194,7 +194,7 @@ export default class RuntimeBackground {
|
||||
},
|
||||
],
|
||||
false,
|
||||
CipherType.Identity
|
||||
CipherType.Identity,
|
||||
);
|
||||
break;
|
||||
}
|
||||
@ -270,13 +270,13 @@ export default class RuntimeBackground {
|
||||
return await this.main.fido2ClientService.createCredential(
|
||||
msg.data,
|
||||
sender.tab,
|
||||
abortController
|
||||
abortController,
|
||||
);
|
||||
} finally {
|
||||
await BrowserApi.focusTab(sender.tab.id);
|
||||
await BrowserApi.focusWindow(sender.tab.windowId);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
case "fido2GetCredentialRequest":
|
||||
return await this.abortManager.runWithAbortController(
|
||||
@ -286,13 +286,13 @@ export default class RuntimeBackground {
|
||||
return await this.main.fido2ClientService.assertCredential(
|
||||
msg.data,
|
||||
sender.tab,
|
||||
abortController
|
||||
abortController,
|
||||
);
|
||||
} finally {
|
||||
await BrowserApi.focusTab(sender.tab.id);
|
||||
await BrowserApi.focusWindow(sender.tab.windowId);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
case "switchAccount": {
|
||||
await this.main.switchAccount(msg.userId);
|
||||
|
@ -23,7 +23,7 @@ export type CipherFileUploadServiceInitOptions = CipherFileUploadServiceFactoyOp
|
||||
|
||||
export function cipherFileUploadServiceFactory(
|
||||
cache: { cipherFileUploadService?: CipherFileUploadServiceAbstraction } & CachedServices,
|
||||
opts: CipherFileUploadServiceInitOptions
|
||||
opts: CipherFileUploadServiceInitOptions,
|
||||
): Promise<CipherFileUploadServiceAbstraction> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -32,7 +32,7 @@ export function cipherFileUploadServiceFactory(
|
||||
async () =>
|
||||
new CipherFileUploadService(
|
||||
await apiServiceFactory(cache, opts),
|
||||
await fileUploadServiceFactory(cache, opts)
|
||||
)
|
||||
await fileUploadServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ export type CipherFileUploadServiceInitOptions = CipherFileUploadServiceFactoyOp
|
||||
|
||||
export function cipherFileUploadServiceFactory(
|
||||
cache: { cipherFileUploadService?: CipherFileUploadServiceAbstraction } & CachedServices,
|
||||
opts: CipherFileUploadServiceInitOptions
|
||||
opts: CipherFileUploadServiceInitOptions,
|
||||
): Promise<CipherFileUploadServiceAbstraction> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -32,7 +32,7 @@ export function cipherFileUploadServiceFactory(
|
||||
async () =>
|
||||
new CipherFileUploadService(
|
||||
await apiServiceFactory(cache, opts),
|
||||
await fileUploadServiceFactory(cache, opts)
|
||||
)
|
||||
await fileUploadServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ export type DevicesApiServiceInitOptions = DevicesApiServiceFactoryOptions & Api
|
||||
|
||||
export function devicesApiServiceFactory(
|
||||
cache: { devicesApiService?: DevicesApiServiceAbstraction } & CachedServices,
|
||||
opts: DevicesApiServiceInitOptions
|
||||
opts: DevicesApiServiceInitOptions,
|
||||
): Promise<DevicesApiServiceAbstraction> {
|
||||
return factory(
|
||||
cache,
|
||||
"devicesApiService",
|
||||
opts,
|
||||
async () => new DevicesApiServiceImplementation(await apiServiceFactory(cache, opts))
|
||||
async () => new DevicesApiServiceImplementation(await apiServiceFactory(cache, opts)),
|
||||
);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ export type EventCollectionServiceInitOptions = EventCollectionServiceOptions &
|
||||
|
||||
export function eventCollectionServiceFactory(
|
||||
cache: { eventCollectionService?: AbstractEventCollectionService } & CachedServices,
|
||||
opts: EventCollectionServiceInitOptions
|
||||
opts: EventCollectionServiceInitOptions,
|
||||
): Promise<AbstractEventCollectionService> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -45,7 +45,7 @@ export function eventCollectionServiceFactory(
|
||||
await cipherServiceFactory(cache, opts),
|
||||
await stateServiceFactory(cache, opts),
|
||||
await organizationServiceFactory(cache, opts),
|
||||
await eventUploadServiceFactory(cache, opts)
|
||||
)
|
||||
await eventUploadServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ export type EventUploadServiceInitOptions = EventUploadServiceOptions &
|
||||
|
||||
export function eventUploadServiceFactory(
|
||||
cache: { eventUploadService?: AbstractEventUploadService } & CachedServices,
|
||||
opts: EventUploadServiceInitOptions
|
||||
opts: EventUploadServiceInitOptions,
|
||||
): Promise<AbstractEventUploadService> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -38,7 +38,7 @@ export function eventUploadServiceFactory(
|
||||
new EventUploadService(
|
||||
await apiServiceFactory(cache, opts),
|
||||
await stateServiceFactory(cache, opts),
|
||||
await logServiceFactory(cache, opts)
|
||||
)
|
||||
await logServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ export type PasswordGenerationServiceInitOptions = PasswordGenerationServiceFact
|
||||
|
||||
export function passwordGenerationServiceFactory(
|
||||
cache: { passwordGenerationService?: PasswordGenerationServiceAbstraction } & CachedServices,
|
||||
opts: PasswordGenerationServiceInitOptions
|
||||
opts: PasswordGenerationServiceInitOptions,
|
||||
): Promise<PasswordGenerationServiceAbstraction> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -40,7 +40,7 @@ export function passwordGenerationServiceFactory(
|
||||
new PasswordGenerationService(
|
||||
await cryptoServiceFactory(cache, opts),
|
||||
await policyServiceFactory(cache, opts),
|
||||
await stateServiceFactory(cache, opts)
|
||||
)
|
||||
await stateServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -23,13 +23,16 @@ export type SearchServiceInitOptions = SearchServiceFactoryOptions &
|
||||
|
||||
export function searchServiceFactory(
|
||||
cache: { searchService?: AbstractSearchService } & CachedServices,
|
||||
opts: SearchServiceInitOptions
|
||||
opts: SearchServiceInitOptions,
|
||||
): Promise<AbstractSearchService> {
|
||||
return factory(
|
||||
cache,
|
||||
"searchService",
|
||||
opts,
|
||||
async () =>
|
||||
new SearchService(await logServiceFactory(cache, opts), await i18nServiceFactory(cache, opts))
|
||||
new SearchService(
|
||||
await logServiceFactory(cache, opts),
|
||||
await i18nServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ export type SendServiceInitOptions = SendServiceFactoryOptions &
|
||||
|
||||
export function sendServiceFactory(
|
||||
cache: { sendService?: InternalSendService } & CachedServices,
|
||||
opts: SendServiceInitOptions
|
||||
opts: SendServiceInitOptions,
|
||||
): Promise<InternalSendService> {
|
||||
return factory(
|
||||
cache,
|
||||
@ -40,7 +40,7 @@ export function sendServiceFactory(
|
||||
await cryptoServiceFactory(cache, opts),
|
||||
await i18nServiceFactory(cache, opts),
|
||||
await cryptoFunctionServiceFactory(cache, opts),
|
||||
await stateServiceFactory(cache, opts)
|
||||
)
|
||||
await stateServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user