mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-11 10:10:25 +01:00
[PM-11481] Incorporate TOTP field qualification to ensure inline menu appears correctly for login forms (#10900)
* [PM-11481] Incorporate TOTP field qualification to ensure inline menu appears correctly for login forms * [PM-11481] Incorporate TOTP field qualification to ensure inline menu appears correctly for login forms
This commit is contained in:
parent
12b5ce548d
commit
4e1912e24e
@ -13,6 +13,7 @@ export type SubmitButtonKeywordsMap = WeakMap<HTMLElement, string>;
|
||||
|
||||
export interface InlineMenuFieldQualificationService {
|
||||
isUsernameField(field: AutofillField): boolean;
|
||||
isCurrentPasswordField(field: AutofillField): boolean;
|
||||
isNewPasswordField(field: AutofillField): boolean;
|
||||
isEmailField(field: AutofillField): boolean;
|
||||
isFieldForLoginForm(field: AutofillField, pageDetails: AutofillPageDetails): boolean;
|
||||
|
@ -87,6 +87,11 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
||||
destroyAutofillInlineMenuListeners: () => this.destroy(),
|
||||
getFormFieldDataForNotification: () => this.handleGetFormFieldDataForNotificationMessage(),
|
||||
};
|
||||
private readonly loginFieldQualifiers: Record<string, CallableFunction> = {
|
||||
[AutofillFieldQualifier.username]: this.inlineMenuFieldQualificationService.isUsernameField,
|
||||
[AutofillFieldQualifier.password]:
|
||||
this.inlineMenuFieldQualificationService.isCurrentPasswordField,
|
||||
};
|
||||
private readonly cardFieldQualifiers: Record<string, CallableFunction> = {
|
||||
[AutofillFieldQualifier.cardholderName]:
|
||||
this.inlineMenuFieldQualificationService.isFieldForCardholderName,
|
||||
@ -781,12 +786,14 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
||||
* @param autofillFieldData - Autofill field data captured from the form field element.
|
||||
*/
|
||||
private qualifyUserFilledLoginField(autofillFieldData: AutofillField) {
|
||||
if (autofillFieldData.type === "password") {
|
||||
autofillFieldData.fieldQualifier = AutofillFieldQualifier.password;
|
||||
return;
|
||||
for (const [fieldQualifier, fieldQualifierFunction] of Object.entries(
|
||||
this.loginFieldQualifiers,
|
||||
)) {
|
||||
if (fieldQualifierFunction(autofillFieldData)) {
|
||||
autofillFieldData.fieldQualifier = fieldQualifier as AutofillFieldQualifierType;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
autofillFieldData.fieldQualifier = AutofillFieldQualifier.username;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,12 +21,29 @@ describe("InlineMenuFieldQualificationService", () => {
|
||||
});
|
||||
|
||||
describe("isFieldForLoginForm", () => {
|
||||
it("disqualifies totp fields", () => {
|
||||
const field = mock<AutofillField>({
|
||||
type: "text",
|
||||
autoCompleteType: "one-time-code",
|
||||
htmlName: "totp",
|
||||
htmlID: "totp",
|
||||
placeholder: "totp",
|
||||
});
|
||||
|
||||
expect(inlineMenuFieldQualificationService.isFieldForLoginForm(field, pageDetails)).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
describe("qualifying a password field for a login form", () => {
|
||||
describe("an invalid password field", () => {
|
||||
it("has a `new-password` autoCompleteType", () => {
|
||||
const field = mock<AutofillField>({
|
||||
type: "password",
|
||||
autoCompleteType: "new-password",
|
||||
htmlName: "input-password",
|
||||
htmlID: "input-password",
|
||||
placeholder: "input-password",
|
||||
});
|
||||
|
||||
expect(inlineMenuFieldQualificationService.isFieldForLoginForm(field, pageDetails)).toBe(
|
||||
@ -39,6 +56,8 @@ describe("InlineMenuFieldQualificationService", () => {
|
||||
type: "password",
|
||||
placeholder: "create account password",
|
||||
autoCompleteType: "",
|
||||
htmlName: "input-password",
|
||||
htmlID: "input-password",
|
||||
});
|
||||
|
||||
expect(inlineMenuFieldQualificationService.isFieldForLoginForm(field, pageDetails)).toBe(
|
||||
|
@ -125,6 +125,7 @@ export class InlineMenuFieldQualificationService
|
||||
this.identityCompanyAutocompleteValue,
|
||||
this.identityPostalCodeAutocompleteValue,
|
||||
]);
|
||||
private totpFieldAutocompleteValue = "one-time-code";
|
||||
private inlineMenuFieldQualificationFlagSet = false;
|
||||
|
||||
constructor() {
|
||||
@ -145,6 +146,11 @@ export class InlineMenuFieldQualificationService
|
||||
return this.isFieldForLoginFormFallback(field);
|
||||
}
|
||||
|
||||
const isTotpField = this.isTotpField(field);
|
||||
if (isTotpField) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const isCurrentPasswordField = this.isCurrentPasswordField(field);
|
||||
if (isCurrentPasswordField) {
|
||||
return this.isPasswordFieldForLoginForm(field, pageDetails);
|
||||
@ -838,7 +844,7 @@ export class InlineMenuFieldQualificationService
|
||||
*
|
||||
* @param field - The field to validate
|
||||
*/
|
||||
private isCurrentPasswordField = (field: AutofillField): boolean => {
|
||||
isCurrentPasswordField = (field: AutofillField): boolean => {
|
||||
if (
|
||||
this.fieldContainsAutocompleteValues(field, this.newPasswordAutoCompleteValue) ||
|
||||
this.keywordsFoundInFieldData(field, this.accountCreationFieldKeywords)
|
||||
@ -875,7 +881,8 @@ export class InlineMenuFieldQualificationService
|
||||
if (
|
||||
(!isInputPasswordType &&
|
||||
this.isExcludedFieldType(field, this.excludedAutofillFieldTypesSet)) ||
|
||||
this.fieldHasDisqualifyingAttributeValue(field)
|
||||
this.fieldHasDisqualifyingAttributeValue(field) ||
|
||||
this.isTotpField(field)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@ -923,6 +930,22 @@ export class InlineMenuFieldQualificationService
|
||||
return !(this.passwordFieldExcludeListString.indexOf(cleanedValue) > -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates whether the provided field is a TOTP field.
|
||||
*
|
||||
* @param field - The field to validate
|
||||
*/
|
||||
private isTotpField = (field: AutofillField): boolean => {
|
||||
if (this.fieldContainsAutocompleteValues(field, this.totpFieldAutocompleteValue)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (
|
||||
!this.isExcludedFieldType(field, this.excludedAutofillFieldTypesSet) &&
|
||||
this.keywordsFoundInFieldData(field, AutoFillConstants.TotpFieldNames)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates the provided field to indicate if the field has a
|
||||
* disqualifying attribute that would impede autofill entirely.
|
||||
|
Loading…
Reference in New Issue
Block a user