Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add extended address field #268

Merged
merged 3 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions apps/browser/src/autofill/enums/autofill-field.enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ export const AutofillFieldQualifier = {
identityEmail: "identityEmail",
identityUsername: "identityUsername",
// Cozy customization
addressLocality: "addressLocality",
addressFloor: "addressFloor",
addressBuilding: "addressBuilding",
addressStairs: "addressStairs",
addressApartment: "addressApartment",
addressEntrycode: "addressEntrycode",
paperIdentityCardNumber: "paperIdentityCardNumber",
paperPassportNumber: "paperPassportNumber",
paperSocialSecurityNumber: "paperSocialSecurityNumber",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ export interface InlineMenuFieldQualificationService {
isFieldForIdentityEmail(field: AutofillField): boolean;
isFieldForIdentityUsername(field: AutofillField): boolean;
// Cozy customization
isFieldForAddressLocality(field: AutofillField): boolean;
isFieldForAddressFloor(field: AutofillField): boolean;
isFieldForAddressBuilding(field: AutofillField): boolean;
isFieldForAddressStairs(field: AutofillField): boolean;
isFieldForAddressApartment(field: AutofillField): boolean;
isFieldForAddressEntrycode(field: AutofillField): boolean;
isFieldForPaperIdentityCardNumber(field: AutofillField): boolean;
isFieldForPaperPassportNumber(field: AutofillField): boolean;
isFieldForPaperSocialSecurityNumber(field: AutofillField): boolean;
Expand Down
26 changes: 26 additions & 0 deletions apps/browser/src/autofill/services/autofill-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,32 @@ export class IdentityAutoFillConstants {

// Cozy customization

export class ContactAutoFillConstants {
static readonly ContactAttributes: string[] = [
"autoCompleteType",
"data-stripe",
"htmlName",
"htmlID",
"label-tag",
"placeholder",
"label-left",
"label-top",
"data-recurly",
];

static readonly AddressLocalityFieldNames: string[] = ["locality", "lieu-dit"];

static readonly AddressFloorFieldNames: string[] = ["floor", "etage"];

static readonly AddressBuildingFieldNames: string[] = ["building", "batiment"];

static readonly AddressStairsFieldNames: string[] = ["stairs", "escalier"];

static readonly AddressApartmentFieldNames: string[] = ["apartment", "appartement"];

static readonly AddressEntrycodeFieldNames: string[] = ["entrycode", "code entrée"];
}

export class PaperAutoFillConstants {
static readonly PaperAttributes: string[] = [
"autoCompleteType",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,18 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
this.inlineMenuFieldQualificationService.isFieldForIdentityUsername,
[AutofillFieldQualifier.password]: this.inlineMenuFieldQualificationService.isNewPasswordField,
// Cozy customization
[AutofillFieldQualifier.addressLocality]:
this.inlineMenuFieldQualificationService.isFieldForAddressLocality,
[AutofillFieldQualifier.addressFloor]:
this.inlineMenuFieldQualificationService.isFieldForAddressFloor,
[AutofillFieldQualifier.addressBuilding]:
this.inlineMenuFieldQualificationService.isFieldForAddressBuilding,
[AutofillFieldQualifier.addressStairs]:
this.inlineMenuFieldQualificationService.isFieldForAddressStairs,
[AutofillFieldQualifier.addressApartment]:
this.inlineMenuFieldQualificationService.isFieldForAddressApartment,
[AutofillFieldQualifier.addressEntrycode]:
this.inlineMenuFieldQualificationService.isFieldForAddressEntrycode,
[AutofillFieldQualifier.paperIdentityCardNumber]:
this.inlineMenuFieldQualificationService.isFieldForPaperIdentityCardNumber,
[AutofillFieldQualifier.paperPassportNumber]:
Expand Down
196 changes: 196 additions & 0 deletions apps/browser/src/autofill/services/autofill.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
} from "./abstractions/autofill.service";
import {
AutoFillConstants,
ContactAutoFillConstants,
CreditCardAutoFillConstants,
IdentityAutoFillConstants,
PaperAutoFillConstants,
Expand Down Expand Up @@ -651,7 +652,13 @@ export default class AutofillService implements AutofillServiceInterface {
const filledFields: { [id: string]: AutofillField } = {};
const fields = options.cipher.fields;

// Cozy customization, skip cipher fields autofill to avoid autofilling two times the same HTML field
// It can happens because we added every contact data in cipher fields
//*
if (fields && fields.length && options.cipher.type !== CipherType.Contact) {
/*/
if (fields && fields.length) {
//*/
const fieldNames: string[] = [];

fields.forEach((f) => {
Expand Down Expand Up @@ -741,6 +748,13 @@ export default class AutofillService implements AutofillServiceInterface {
options,
);

fillScript = await this.generateContactAddressFillScript(
fillScript,
pageDetails,
filledFields,
options,
);

fillScript = await this.generatePaperFillScript(
fillScript,
pageDetails,
Expand Down Expand Up @@ -1572,6 +1586,188 @@ export default class AutofillService implements AutofillServiceInterface {

// Cozy customization

/**
* Generates the autofill script for the specified page details and contact data that is not already generated in the generateIdentityFillScript method.
* We decided to add a new generateFillScript method because :
* - we prefer to keep the generateIdentityFillScript from Bitwarden untouched
* - it makes no sense in our generatePaperFillScript
* @param {AutofillScript} fillScript
* @param {AutofillPageDetails} pageDetails
* @param {{[p: string]: AutofillField}} filledFields
* @param {GenerateFillScriptOptions} options
* @returns {AutofillScript}
* @private
*/
private async generateContactAddressFillScript(
fillScript: AutofillScript,
pageDetails: AutofillPageDetails,
filledFields: { [id: string]: AutofillField },
options: GenerateFillScriptOptions,
): Promise<AutofillScript> {
const fillFields: { [id: string]: AutofillField } = {};

pageDetails.fields.forEach((f) => {
if (
AutofillService.isExcludedFieldType(f, AutoFillConstants.ExcludedAutofillTypes) ||
["current-password", "new-password"].includes(f.autoCompleteType)
) {
return;
}

for (let i = 0; i < ContactAutoFillConstants.ContactAttributes.length; i++) {
const attr = ContactAutoFillConstants.ContactAttributes[i];
// eslint-disable-next-line
if (!f.hasOwnProperty(attr) || !f[attr] || !f.viewable) {
continue;
}
if (
!fillFields.contactAddressLocality &&
AutofillService.isFieldMatch(f[attr], ContactAutoFillConstants.AddressLocalityFieldNames)
) {
fillFields.contactAddressLocality = f;
break;
}
if (
!fillFields.contactAddressFloor &&
AutofillService.isFieldMatch(f[attr], ContactAutoFillConstants.AddressFloorFieldNames)
) {
fillFields.contactAddressFloor = f;
break;
}
if (
!fillFields.contactAddressBuilding &&
AutofillService.isFieldMatch(f[attr], ContactAutoFillConstants.AddressBuildingFieldNames)
) {
fillFields.contactAddressBuilding = f;
break;
}
if (
!fillFields.contactAddressStairs &&
AutofillService.isFieldMatch(f[attr], ContactAutoFillConstants.AddressStairsFieldNames)
) {
fillFields.contactAddressStairs = f;
break;
}
if (
!fillFields.contactAddressApartment &&
AutofillService.isFieldMatch(f[attr], ContactAutoFillConstants.AddressApartmentFieldNames)
) {
fillFields.contactAddressApartment = f;
break;
}
if (
!fillFields.contactAddressEntrycode &&
AutofillService.isFieldMatch(f[attr], ContactAutoFillConstants.AddressEntrycodeFieldNames)
) {
fillFields.contactAddressEntrycode = f;
break;
}
}
});

const client = await this.cozyClientService.getClientInstance();

if (fillFields.contactAddressLocality) {
const addressLocality = await getCozyValue({
client,
contactId: options.cipher.id,
fieldQualifier: "addressLocality",
cozyAutofillOptions: options.cozyAutofillOptions,
});

this.makeScriptActionWithValue(
fillScript,
addressLocality,
fillFields.contactAddressLocality,
filledFields,
);
}

if (fillFields.contactAddressFloor) {
const addressFloor = await getCozyValue({
client,
contactId: options.cipher.id,
fieldQualifier: "addressFloor",
cozyAutofillOptions: options.cozyAutofillOptions,
});

this.makeScriptActionWithValue(
fillScript,
addressFloor,
fillFields.contactAddressFloor,
filledFields,
);
}

if (fillFields.contactAddressBuilding) {
const addressBuilding = await getCozyValue({
client,
contactId: options.cipher.id,
fieldQualifier: "addressBuilding",
cozyAutofillOptions: options.cozyAutofillOptions,
});

this.makeScriptActionWithValue(
fillScript,
addressBuilding,
fillFields.contactAddressBuilding,
filledFields,
);
}

if (fillFields.contactAddressStairs) {
const addressStairs = await getCozyValue({
client,
contactId: options.cipher.id,
fieldQualifier: "addressStairs",
cozyAutofillOptions: options.cozyAutofillOptions,
});

this.makeScriptActionWithValue(
fillScript,
addressStairs,
fillFields.contactAddressStairs,
filledFields,
);
}

if (fillFields.contactAddressApartment) {
const addressApartment = await getCozyValue({
client,
contactId: options.cipher.id,
fieldQualifier: "addressApartment",
cozyAutofillOptions: options.cozyAutofillOptions,
});

this.makeScriptActionWithValue(
fillScript,
addressApartment,
fillFields.contactAddressApartment,
filledFields,
);
}

if (fillFields.contactAddressEntrycode) {
const addressEntrycode = await getCozyValue({
client,
contactId: options.cipher.id,
fieldQualifier: "addressEntrycode",
cozyAutofillOptions: options.cozyAutofillOptions,
});

this.makeScriptActionWithValue(
fillScript,
addressEntrycode,
fillFields.contactAddressEntrycode,
filledFields,
);
}

return fillScript;
}

// Cozy customization end

/**
* Generates the autofill script for the specified page details and paper data.
* @param {AutofillScript} fillScript
Expand Down
Loading
Loading