From d2c24792fe86bea9cc7f3e2015225081f57f1c19 Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Thu, 20 Feb 2025 23:16:49 +0100 Subject: [PATCH] Simplify form detector password confirm (#541) --- .../src/shared/formDetector/FieldPatterns.ts | 4 - .../src/shared/formDetector/FormDetector.ts | 46 +- .../__tests__/FormDetector.en.test.ts | 11 + .../test-forms/en-registration-form4.html | 727 ++++++++++++++++++ 4 files changed, 741 insertions(+), 47 deletions(-) create mode 100644 browser-extensions/chrome/src/shared/formDetector/__tests__/test-forms/en-registration-form4.html diff --git a/browser-extensions/chrome/src/shared/formDetector/FieldPatterns.ts b/browser-extensions/chrome/src/shared/formDetector/FieldPatterns.ts index fe46dff7e..9603593c9 100644 --- a/browser-extensions/chrome/src/shared/formDetector/FieldPatterns.ts +++ b/browser-extensions/chrome/src/shared/formDetector/FieldPatterns.ts @@ -8,7 +8,6 @@ export type FieldPatterns = { email: string[]; emailConfirm: string[]; password: string[]; - passwordConfirm: string[]; birthdate: string[]; gender: string[]; birthDateDay: string[]; @@ -35,7 +34,6 @@ export const EnglishFieldPatterns: FieldPatterns = { email: ['email', 'mail', 'emailaddress'], emailConfirm: ['confirm', 'verification', 'repeat', 'retype', 'verify'], password: ['password', 'pwd', 'pass'], - passwordConfirm: ['confirm', 'verification', 'repeat', 'retype', '2', 'verify'], birthdate: ['birthdate', 'birth-date', 'dob', 'date-of-birth'], gender: ['gender', 'sex'], birthDateDay: ['birth-day', 'birthday', 'day', 'birthdate_d'], @@ -62,7 +60,6 @@ export const DutchFieldPatterns: FieldPatterns = { email: ['e-mailadres', 'e-mail'], emailConfirm: ['bevestig', 'herhaal', 'verificatie'], password: ['wachtwoord', 'pwd'], - passwordConfirm: ['bevestig', 'herhaal', 'verificatie'], birthdate: ['geboortedatum', 'geboorte-datum'], gender: ['geslacht', 'aanhef'], birthDateDay: ['dag'], @@ -95,7 +92,6 @@ export const CombinedFieldPatterns: FieldPatterns = { email: [...new Set([...DutchFieldPatterns.email, ...EnglishFieldPatterns.email])], emailConfirm: [...new Set([...EnglishFieldPatterns.emailConfirm, ...DutchFieldPatterns.emailConfirm])], password: [...new Set([...EnglishFieldPatterns.password, ...DutchFieldPatterns.password])], - passwordConfirm: [...new Set([...EnglishFieldPatterns.passwordConfirm, ...DutchFieldPatterns.passwordConfirm])], birthdate: [...new Set([...EnglishFieldPatterns.birthdate, ...DutchFieldPatterns.birthdate])], gender: [...new Set([...EnglishFieldPatterns.gender, ...DutchFieldPatterns.gender])], birthDateDay: [...new Set([...EnglishFieldPatterns.birthDateDay, ...DutchFieldPatterns.birthDateDay])], diff --git a/browser-extensions/chrome/src/shared/formDetector/FormDetector.ts b/browser-extensions/chrome/src/shared/formDetector/FormDetector.ts index 502c3432d..d37dbd284 100644 --- a/browser-extensions/chrome/src/shared/formDetector/FormDetector.ts +++ b/browser-extensions/chrome/src/shared/formDetector/FormDetector.ts @@ -291,51 +291,11 @@ export class FormDetector { ? form.querySelectorAll('input[type="password"]') : this.document.querySelectorAll('input[type="password"]'); - let primaryPassword: HTMLInputElement | null = null; - let confirmPassword: HTMLInputElement | null = null; - - // Look for the first password field that doesn't appear to be a confirmation field - for (const input of Array.from(candidates)) { - const attributes = [ - input.id, - input.name, - input.placeholder - ].map(attr => attr?.toLowerCase() ?? ''); - - if (!CombinedFieldPatterns.passwordConfirm.some(pattern => attributes.some(attr => attr.includes(pattern)))) { - primaryPassword = input; - break; - } - } - - // If no clear primary password field is found, use the first password field as primary - if (!primaryPassword && candidates.length > 0) { - primaryPassword = candidates[0]; - } - - // If we found a primary password, look for a confirmation field - if (primaryPassword) { - for (const input of Array.from(candidates)) { - if (input === primaryPassword) continue; - - const attributes = [ - input.id, - input.name, - input.className, - input.placeholder - ].map(attr => attr?.toLowerCase() ?? ''); - - const confirmPatterns = ['confirm', 'verification', 'repeat', 'retype', '2', 'verify']; - if (confirmPatterns.some(pattern => attributes.some(attr => attr.includes(pattern)))) { - confirmPassword = input; - break; - } - } - } + const candidateArray = Array.from(candidates); return { - primary: primaryPassword, - confirm: confirmPassword + primary: candidateArray[0] ?? null, + confirm: candidateArray[1] ?? null }; } diff --git a/browser-extensions/chrome/src/shared/formDetector/__tests__/FormDetector.en.test.ts b/browser-extensions/chrome/src/shared/formDetector/__tests__/FormDetector.en.test.ts index dbeb1b03f..c694de033 100644 --- a/browser-extensions/chrome/src/shared/formDetector/__tests__/FormDetector.en.test.ts +++ b/browser-extensions/chrome/src/shared/formDetector/__tests__/FormDetector.en.test.ts @@ -33,6 +33,17 @@ describe('FormDetector English tests', () => { testField(FormField.EmailConfirm, 'reenter_email', htmlFile); }); + describe('English registration form 4 detection', () => { + const htmlFile = 'en-registration-form4.html'; + + testField(FormField.Email, 'fbclc_userName', htmlFile); + testField(FormField.EmailConfirm, 'fbclc_emailConf', htmlFile); + testField(FormField.Password, 'fbclc_pwd', htmlFile); + testField(FormField.PasswordConfirm, 'fbclc_pwdConf', htmlFile); + testField(FormField.FirstName, 'fbclc_fName', htmlFile); + testField(FormField.LastName, 'fbclc_lName', htmlFile); + }); + describe('English email form 1 detection', () => { const htmlFile = 'en-email-form1.html'; diff --git a/browser-extensions/chrome/src/shared/formDetector/__tests__/test-forms/en-registration-form4.html b/browser-extensions/chrome/src/shared/formDetector/__tests__/test-forms/en-registration-form4.html new file mode 100644 index 000000000..20152f11a --- /dev/null +++ b/browser-extensions/chrome/src/shared/formDetector/__tests__/test-forms/en-registration-form4.html @@ -0,0 +1,727 @@ +
+ + + + + + +
+
+ + + + + + + + + +
+
+ +

+ Already a registered user? + Please sign in + +

+ +

+ Login credentials are case-sensitive +

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + +
+ + + + +
+ + +
+ + + +
+ +
+ + + +
Password accepted
+ + +
+ + + +
+ + + +
+ +
+ +
 Passwords don’t match
+ + +
Passwords don’t match
+ + + +
+ + + +
+ + + +
+ + + + +
+ + +
+ + +
+
+ +
+
+
+ + + +
+ +
+
+ + + + + +
+
+
\ No newline at end of file