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",
|
"verification code",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
static readonly RecoveryCodeFieldNames: string[] = ["backup", "recovery"];
|
||||||
|
|
||||||
static readonly AmbiguousTotpFieldNames: string[] = ["code", "pin", "otc", "otp", "2fa", "mfa"];
|
static readonly AmbiguousTotpFieldNames: string[] = ["code", "pin", "otc", "otp", "2fa", "mfa"];
|
||||||
|
|
||||||
static readonly SearchFieldNames: string[] = ["search", "query", "find", "go"];
|
static readonly SearchFieldNames: string[] = ["search", "query", "find", "go"];
|
||||||
|
|||||||
@@ -4487,6 +4487,34 @@ describe("AutofillService", () => {
|
|||||||
|
|
||||||
expect(result).toBe(totpField);
|
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", () => {
|
describe("findMatchingFieldIndex", () => {
|
||||||
|
|||||||
@@ -948,7 +948,8 @@ export default class AutofillService implements AutofillServiceInterface {
|
|||||||
...AutoFillConstants.TotpFieldNames,
|
...AutoFillConstants.TotpFieldNames,
|
||||||
...AutoFillConstants.AmbiguousTotpFieldNames,
|
...AutoFillConstants.AmbiguousTotpFieldNames,
|
||||||
]) ||
|
]) ||
|
||||||
field.autoCompleteType === "one-time-code");
|
field.autoCompleteType === "one-time-code") &&
|
||||||
|
!AutofillService.fieldIsFuzzyMatch(field, [...AutoFillConstants.RecoveryCodeFieldNames]);
|
||||||
|
|
||||||
const isFillableUsernameField =
|
const isFillableUsernameField =
|
||||||
!options.skipUsernameOnlyFill &&
|
!options.skipUsernameOnlyFill &&
|
||||||
@@ -2357,11 +2358,15 @@ export default class AutofillService implements AutofillServiceInterface {
|
|||||||
(canBeReadOnly || !f.readonly) &&
|
(canBeReadOnly || !f.readonly) &&
|
||||||
(withoutForm || f.form === passwordField.form) &&
|
(withoutForm || f.form === passwordField.form) &&
|
||||||
(canBeHidden || f.viewable) &&
|
(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, [
|
AutofillService.fieldIsFuzzyMatch(f, [
|
||||||
...AutoFillConstants.TotpFieldNames,
|
...AutoFillConstants.TotpFieldNames,
|
||||||
...AutoFillConstants.AmbiguousTotpFieldNames,
|
...AutoFillConstants.AmbiguousTotpFieldNames,
|
||||||
])
|
]) &&
|
||||||
|
!AutofillService.fieldIsFuzzyMatch(f, [...AutoFillConstants.RecoveryCodeFieldNames])
|
||||||
) {
|
) {
|
||||||
totpField = f;
|
totpField = f;
|
||||||
|
|
||||||
@@ -2551,7 +2556,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
|||||||
if (!AutofillService.hasValue(value)) {
|
if (!AutofillService.hasValue(value)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (this.fuzzyMatch(names, value)) {
|
if (AutofillService.fuzzyMatch(names, value)) {
|
||||||
return showMatch ? [true, { attr, value }] : true;
|
return showMatch ? [true, { attr, value }] : true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2567,7 +2572,13 @@ export default class AutofillService implements AutofillServiceInterface {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private static fuzzyMatch(options: string[], value: string): boolean {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
SubmitChangePasswordButtonNames,
|
SubmitChangePasswordButtonNames,
|
||||||
SubmitLoginButtonNames,
|
SubmitLoginButtonNames,
|
||||||
} from "./autofill-constants";
|
} from "./autofill-constants";
|
||||||
|
import AutofillService from "./autofill.service";
|
||||||
|
|
||||||
export class InlineMenuFieldQualificationService
|
export class InlineMenuFieldQualificationService
|
||||||
implements InlineMenuFieldQualificationServiceInterface
|
implements InlineMenuFieldQualificationServiceInterface
|
||||||
@@ -1071,6 +1072,10 @@ export class InlineMenuFieldQualificationService
|
|||||||
* @param field - The field to validate
|
* @param field - The field to validate
|
||||||
*/
|
*/
|
||||||
isTotpField = (field: AutofillField): boolean => {
|
isTotpField = (field: AutofillField): boolean => {
|
||||||
|
if (AutofillService.fieldIsFuzzyMatch(field, [...AutoFillConstants.RecoveryCodeFieldNames])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.fieldContainsAutocompleteValues(field, this.totpFieldAutocompleteValue)) {
|
if (this.fieldContainsAutocompleteValues(field, this.totpFieldAutocompleteValue)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user