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

Foundation of paper autofilling paper data with id card number #222

Merged
merged 7 commits into from
Jul 23, 2024
32 changes: 32 additions & 0 deletions apps/browser/docs/T08.0-Identity-with-paper-data.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<link rel="stylesheet" media="screen" type="text/css" href="TXX.css"/>
</head>

<body>

<a href="./">Back to menu</a>
<hr>
<h2>Identity form with paper data</h2>
<p>autofill should insert data from io.cozy.files data if they exist for the autofilled io.cozy.contacts</p>

<form class="form autosave-enabled" id="dossier-edit-form" method="post">
<div class="editable-champ editable-champ-text">
<label for="name">Nom de famille
</label>
<input placeholder="Nom de famille" required="required" type="text" value="" id="name">
</div>

<div class="editable-champ editable-champ-text" >
<label for="numCni">Numéro de carte d'identité
</label>
<input placeholder="Numéro de carte d'identité" required="required" type="text" value="" id="numCni">
</div>

</form>

</body>
</html>
1 change: 1 addition & 0 deletions apps/browser/docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ <h2>Index of forms to test the browser addon of Cozy Pass</h2>
<li><a href="T03.5-identity-with-a-lastname-and-firstname-filed-EN.html" >Identity form - with a field asking for lastName and firstName -EN</a></li>
<li><a href="T03.4-identity-with-a-firstname-and-lastname-filed-DE.html" >Identity form - with a field asking for firstName and lastName -DE</a></li>
<li><a href="T03.5-identity-with-a-lastname-and-firstname-filed-DE.html" >Identity form - with a field asking for lastName and firstName -DE</a></li>
<li><a href="T08.0-Identity-with-paper-data.html" >Identity form - with paper data</a></li>
</ul>
</li>
<br>
Expand Down
3 changes: 3 additions & 0 deletions apps/browser/src/autofill/enums/autofill-field.enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ export const AutofillFieldQualifier = {
identityPhone: "identityPhone",
identityEmail: "identityEmail",
identityUsername: "identityUsername",
// Cozy customization
paperIdentityCardNumber: "paperIdentityCardNumber",
// Cozy customization end
} as const;

export type AutofillFieldQualifierType =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,7 @@ export interface InlineMenuFieldQualificationService {
isFieldForIdentityPhone(field: AutofillField): boolean;
isFieldForIdentityEmail(field: AutofillField): boolean;
isFieldForIdentityUsername(field: AutofillField): boolean;
// Cozy customization
isFieldForPaperIdentityCardNumber(field: AutofillField): boolean;
// Cozy customization end
}
50 changes: 50 additions & 0 deletions apps/browser/src/autofill/services/autofill-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -829,3 +829,53 @@ export class IdentityAutoFillConstants {
saskatchewan: "SK",
};
}

// Cozy customization

export class PaperAutoFillConstants {
static readonly PaperAttributes: string[] = [
"autoCompleteType",
"data-stripe",
"htmlName",
"htmlID",
"label-tag",
"placeholder",
"label-left",
"label-top",
"data-recurly",
];
paultranvan marked this conversation as resolved.
Show resolved Hide resolved

static readonly IdentityCardNumberFieldNames: string[] = [
"cniNum",
"numCni",
"idcni",
"cniId",
"numeroCarteIdendite",
"carteIdenditeNumero",
"carteidentite ",
"Numéro de la carte d'identité",
"Numéro d'identification",
"Numéro d'identité",
"Numéro de pièce d'identité",
"Numéro de carte d'identité",
"Identifiant personnel",
"Identifiant d'identification",
"ID de carte d'identité",
"Code d'identification",
"Numéro d'identification officiel",
"Numéro d'enregistrement personnel",
"Identity card number",
"Identification number",
"Identity number",
"Identity document number",
"Identity card number",
"Personal identifier",
"Identification ID",
"ID card ",
"Identification code",
"Official identification number",
"Personal registration number",
];
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a huge list 😮 You did it yourself?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it is our awesome product owner.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, but I wonder if it's worth the effort to do it for every type of data. And also, I tend to think that we should do it with real-case examples, as:

  • it will avoid trying to imagine all possible cases
  • we should be careful with false positive: typically "Personal identifier" seems rather generic and not related to french ID card (also, it's worth questioning the need to support english keywords for very-french data such as this one).
    What do you think @BenjaminMty ?


// Cozy customization end
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
this.inlineMenuFieldQualificationService.isFieldForIdentityEmail,
[AutofillFieldQualifier.identityUsername]:
this.inlineMenuFieldQualificationService.isFieldForIdentityUsername,
// Cozy customization
[AutofillFieldQualifier.paperIdentityCardNumber]:
this.inlineMenuFieldQualificationService.isFieldForPaperIdentityCardNumber,
// Cozy customization end
};

constructor(private inlineMenuFieldQualificationService: InlineMenuFieldQualificationService) {}
Expand Down
5 changes: 5 additions & 0 deletions apps/browser/src/autofill/services/autofill.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import { LoginView } from "@bitwarden/common/vault/models/view/login.view";
import { CipherService } from "@bitwarden/common/vault/services/cipher.service";
import { TotpService } from "@bitwarden/common/vault/services/totp.service";

import { CozyClientService } from "src/popup/services/cozyClient.service";

import { BrowserApi } from "../../platform/browser/browser-api";
import { BrowserScriptInjectorService } from "../../platform/services/browser-script-injector.service";
import { AutofillMessageCommand, AutofillMessageSender } from "../enums/autofill-message.enums";
Expand Down Expand Up @@ -89,6 +91,7 @@ describe("AutofillService", () => {
let authService: MockProxy<AuthService>;
let configService: MockProxy<ConfigService>;
let messageListener: MockProxy<MessageListener>;
let cozyClientService: MockProxy<CozyClientService>;

beforeEach(() => {
scriptInjectorService = new BrowserScriptInjectorService(platformUtilsService, logService);
Expand All @@ -100,6 +103,7 @@ describe("AutofillService", () => {
authService.activeAccountStatus$ = activeAccountStatusMock$;
configService = mock<ConfigService>();
messageListener = mock<MessageListener>();
cozyClientService = mock<CozyClientService>();
autofillService = new AutofillService(
cipherService,
autofillSettingsService,
Expand All @@ -114,6 +118,7 @@ describe("AutofillService", () => {
authService,
configService,
messageListener,
cozyClientService,
);
domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider);
domainSettingsService.equivalentDomains$ = of(mockEquivalentDomains);
Expand Down
77 changes: 77 additions & 0 deletions apps/browser/src/autofill/services/autofill.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,15 @@ import {
AutoFillConstants,
CreditCardAutoFillConstants,
IdentityAutoFillConstants,
PaperAutoFillConstants,
} from "./autofill-constants";

/* start Cozy imports */
/* eslint-disable */
import { CozyClientService } from "src/popup/services/cozyClient.service";
import { generateIdentityViewFromCipherView } from "../../../../../libs/cozy/contact.helper";
import { IdentityView } from "@bitwarden/common/vault/models/view/identity.view";
import { getCozyValue } from "../../../../../libs/cozy/mapping";
/* eslint-enable */
/* end Cozy imports */

Expand All @@ -78,6 +81,7 @@ export default class AutofillService implements AutofillServiceInterface {
private authService: AuthService,
private configService: ConfigService,
private messageListener: MessageListener,
private cozyClientService: CozyClientService,
) {}

/**
Expand Down Expand Up @@ -668,6 +672,13 @@ export default class AutofillService implements AutofillServiceInterface {
options,
);

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

options.cipher.identity = new IdentityView();
break;
// Cozy customization end
Expand Down Expand Up @@ -1486,6 +1497,72 @@ export default class AutofillService implements AutofillServiceInterface {
return fillScript;
}

// Cozy customization

/**
* Generates the autofill script for the specified page details and paper data.
* @param {AutofillScript} fillScript
* @param {AutofillPageDetails} pageDetails
* @param {{[p: string]: AutofillField}} filledFields
* @param {GenerateFillScriptOptions} options
* @returns {AutofillScript}
* @private
*/
private async generatePaperFillScript(
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 < PaperAutoFillConstants.PaperAttributes.length; i++) {
const attr = PaperAutoFillConstants.PaperAttributes[i];
// eslint-disable-next-line
if (!f.hasOwnProperty(attr) || !f[attr] || !f.viewable) {
continue;
}
// FIXME: Check if we will be able to factorize the code
if (
!fillFields.paperIdentityCardNumber &&
AutofillService.isFieldMatch(f[attr], PaperAutoFillConstants.IdentityCardNumberFieldNames)
) {
fillFields.paperIdentityCardNumber = f;
break;
}
paultranvan marked this conversation as resolved.
Show resolved Hide resolved
}
});

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

// FIXME: Check if we will be able to factorize the code
if (fillFields.paperIdentityCardNumber) {
const paperIdentityCardNumber = await getCozyValue({
client,
contactId: options.cipher.id,
fieldQualifier: "paperIdentityCardNumber",
});
paultranvan marked this conversation as resolved.
Show resolved Hide resolved
this.makeScriptActionWithValue(
fillScript,
paperIdentityCardNumber,
fillFields.paperIdentityCardNumber,
filledFields,
);
}

return fillScript;
}

// Cozy customization end

/**
* Accepts an HTMLInputElement type value and a list of
* excluded types and returns true if the type is excluded.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
AutoFillConstants,
CreditCardAutoFillConstants,
IdentityAutoFillConstants,
PaperAutoFillConstants,
} from "./autofill-constants";

export class InlineMenuFieldQualificationService
Expand Down Expand Up @@ -137,6 +138,9 @@ export class InlineMenuFieldQualificationService
...IdentityAutoFillConstants.PhoneFieldNames,
...IdentityAutoFillConstants.EmailFieldNames,
...IdentityAutoFillConstants.UserNameFieldNames,
// Cozy customization
...PaperAutoFillConstants.IdentityCardNumberFieldNames,
// Cozy customization end
]),
];
private inlineMenuFieldQualificationFlagSet = false;
Expand Down Expand Up @@ -825,6 +829,26 @@ export class InlineMenuFieldQualificationService
);
};

// Cozy customization

/**
* Validates the provided field as an identity username field.
*
* @param field - The field to validate
*/
isFieldForPaperIdentityCardNumber = (field: AutofillField): boolean => {
return (
!this.fieldContainsAutocompleteValues(field, this.autocompleteDisabledValues) &&
this.keywordsFoundInFieldData(
field,
PaperAutoFillConstants.IdentityCardNumberFieldNames,
false,
)
);
};

// Cozy customization end

/**
* Validates the provided field as a username field.
*
Expand Down Expand Up @@ -1025,10 +1049,21 @@ export class InlineMenuFieldQualificationService
) {
const searchedValues = this.getAutofillFieldDataKeywords(autofillFieldData, fuzzyMatchKeywords);
if (typeof searchedValues === "string") {
// Cozy customization, compare lowercase keyword and lowercase searchedValue
//*
return keywords.some((keyword) => searchedValues.indexOf(keyword.toLowerCase()) > -1);
/*/
return keywords.some((keyword) => searchedValues.indexOf(keyword) > -1);
//*/
}

// Cozy customization, compare lowercase keyword and lowercase searchedValue
//*
return keywords.some((keyword) => searchedValues.has(keyword.toLowerCase()));

/*/
return keywords.some((keyword) => searchedValues.has(keyword));
//*/
}

/**
Expand Down
1 change: 1 addition & 0 deletions apps/browser/src/background/main.background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,7 @@ export default class MainBackground {
this.authService,
this.configService,
messageListener,
this.cozyClientService,
);
this.auditService = new AuditService(this.cryptoFunctionService, this.apiService);

Expand Down
1 change: 1 addition & 0 deletions apps/browser/src/popup/services/services.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ const safeProviders: SafeProvider[] = [
AuthService,
ConfigService,
MessageListener,
CozyClientService,
],
}),
safeProvider({
Expand Down
Loading
Loading