mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 09:43:23 +00:00
PM-24657 - Cannot fill TOTP code into reddit.com during login (#16218)
* PM-24657 - exclude backup fields from totp qualifiers and autofill * add tests for htmlID and htmlName for backup code exclusion * add comments to justify tel addition * Update apps/browser/src/autofill/services/autofill.service.ts Co-authored-by: Jonathan Prusik <jprusik@users.noreply.github.com> * update constant name to match recovery codes --------- Co-authored-by: Jonathan Prusik <jprusik@users.noreply.github.com>
This commit is contained in:
@@ -46,6 +46,8 @@ export class AutoFillConstants {
|
||||
"verification code",
|
||||
];
|
||||
|
||||
static readonly RecoveryCodeFieldNames: string[] = ["backup", "recovery"];
|
||||
|
||||
static readonly AmbiguousTotpFieldNames: string[] = ["code", "pin", "otc", "otp", "2fa", "mfa"];
|
||||
|
||||
static readonly SearchFieldNames: string[] = ["search", "query", "find", "go"];
|
||||
|
||||
@@ -4487,6 +4487,34 @@ describe("AutofillService", () => {
|
||||
|
||||
expect(result).toBe(totpField);
|
||||
});
|
||||
|
||||
it("returns null if the totp field matches excluded TOTP field names via htmlID", () => {
|
||||
totpField.htmlID = "recovery-code";
|
||||
|
||||
const result = autofillService["findTotpField"](
|
||||
pageDetails,
|
||||
passwordField,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it("returns null if the totp field matches excluded TOTP field names via htmlName", () => {
|
||||
totpField.htmlName = "backup";
|
||||
|
||||
const result = autofillService["findTotpField"](
|
||||
pageDetails,
|
||||
passwordField,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("findMatchingFieldIndex", () => {
|
||||
|
||||
@@ -948,7 +948,8 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
...AutoFillConstants.TotpFieldNames,
|
||||
...AutoFillConstants.AmbiguousTotpFieldNames,
|
||||
]) ||
|
||||
field.autoCompleteType === "one-time-code");
|
||||
field.autoCompleteType === "one-time-code") &&
|
||||
!AutofillService.fieldIsFuzzyMatch(field, [...AutoFillConstants.RecoveryCodeFieldNames]);
|
||||
|
||||
const isFillableUsernameField =
|
||||
!options.skipUsernameOnlyFill &&
|
||||
@@ -2357,11 +2358,15 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
(canBeReadOnly || !f.readonly) &&
|
||||
(withoutForm || f.form === passwordField.form) &&
|
||||
(canBeHidden || f.viewable) &&
|
||||
(f.type === "text" || f.type === "number") &&
|
||||
(f.type === "text" ||
|
||||
f.type === "number" ||
|
||||
// sites will commonly use tel in order to get the digit pad against semantic recommendations
|
||||
f.type === "tel") &&
|
||||
AutofillService.fieldIsFuzzyMatch(f, [
|
||||
...AutoFillConstants.TotpFieldNames,
|
||||
...AutoFillConstants.AmbiguousTotpFieldNames,
|
||||
])
|
||||
]) &&
|
||||
!AutofillService.fieldIsFuzzyMatch(f, [...AutoFillConstants.RecoveryCodeFieldNames])
|
||||
) {
|
||||
totpField = f;
|
||||
|
||||
@@ -2551,7 +2556,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
if (!AutofillService.hasValue(value)) {
|
||||
continue;
|
||||
}
|
||||
if (this.fuzzyMatch(names, value)) {
|
||||
if (AutofillService.fuzzyMatch(names, value)) {
|
||||
return showMatch ? [true, { attr, value }] : true;
|
||||
}
|
||||
}
|
||||
@@ -2567,7 +2572,13 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
* @private
|
||||
*/
|
||||
private static fuzzyMatch(options: string[], value: string): boolean {
|
||||
if (options == null || options.length === 0 || value == null || value === "") {
|
||||
if (
|
||||
options == null ||
|
||||
options.length === 0 ||
|
||||
value == null ||
|
||||
typeof value !== "string" ||
|
||||
value.length < 1
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
SubmitChangePasswordButtonNames,
|
||||
SubmitLoginButtonNames,
|
||||
} from "./autofill-constants";
|
||||
import AutofillService from "./autofill.service";
|
||||
|
||||
export class InlineMenuFieldQualificationService
|
||||
implements InlineMenuFieldQualificationServiceInterface
|
||||
@@ -1071,6 +1072,10 @@ export class InlineMenuFieldQualificationService
|
||||
* @param field - The field to validate
|
||||
*/
|
||||
isTotpField = (field: AutofillField): boolean => {
|
||||
if (AutofillService.fieldIsFuzzyMatch(field, [...AutoFillConstants.RecoveryCodeFieldNames])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.fieldContainsAutocompleteValues(field, this.totpFieldAutocompleteValue)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user