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

Bug fixes for stream1 #191

Merged
merged 11 commits into from
Apr 25, 2024
Merged
6 changes: 0 additions & 6 deletions apps/browser/src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1819,12 +1819,6 @@
"message": "Max access count reached",
"description": "This text will be displayed after a Send has been accessed the maximum amount of times."
},
"expired": {
"message": "Expired"
},
"expiredIn": {
"message": "Expire in"
},
"pendingDeletion": {
"message": "Pending deletion"
},
Expand Down
6 changes: 0 additions & 6 deletions apps/browser/src/_locales/fr/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1867,12 +1867,6 @@
"message": "Nombre maximum d'accès atteint",
"description": "This text will be displayed after a Send has been accessed the maximum amount of times."
},
"expired": {
"message": "Expiré"
},
"expiredIn": {
"message": "Expire dans"
},
"pendingDeletion": {
"message": "En attente de suppression"
},
Expand Down
7 changes: 6 additions & 1 deletion apps/browser/src/autofill/services/autofill.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -926,7 +926,12 @@ export default class AutofillService implements AutofillServiceInterface {
/*
For contacts, we create an IdentityView with the contact content to leverage the generateIdentityFillScript.
*/
options.cipher.identity = generateIdentityViewFromCipherView(options.cipher);
try {
options.cipher.identity = generateIdentityViewFromCipherView(options.cipher);
} catch (e) {
// eslint-disable-next-line no-console
console.log("Failed to convert CipherView to IdentityView", e);
}

fillScript = this.generateIdentityFillScript(
fillScript,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
·
<span *ngIf="field.expirationData.isExpired" class="text-danger">
{{ "expired" | i18n }}
{{ message }}
</span>
<span *ngIf="field.expirationData.isExpiringSoon" class="text-warning">
{{ "expiredIn" | i18n }} {{ getExpirationDistance() }}
{{ message }}
</span>
Original file line number Diff line number Diff line change
@@ -1,25 +1,42 @@
/* eslint-disable import/no-duplicates */
import { Component, Input } from "@angular/core";
import formatDistanceToNowStrict from "date-fns/formatDistanceToNowStrict";
import fr from "date-fns/locale/fr";
import { Component, Input, OnInit } from "@angular/core";
import { models } from "cozy-client";

import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { FieldView } from "@bitwarden/common/vault/models/view/field.view";

const { makeExpiredMessage, makeExpiresInMessage } = models.paper;

@Component({
selector: "app-vault-view-expiration-date",
templateUrl: "./view-expiration-date.component.html",
})
export class ViewExpirationDateComponent {
export class ViewExpirationDateComponent implements OnInit {
@Input() field: FieldView;
message: string;

constructor(private i18nService: I18nService) {}

getExpirationDistance(): string {
return formatDistanceToNowStrict(
new Date(this.field.expirationData.expirationDate),
ngOnInit() {
if (this.field.expirationData.isExpired) {
this.message = this.getExpiredMessage();
} else if (this.field.expirationData.isExpiringSoon) {
this.message = this.getExpiresInMessage();
}
}

private getExpiredMessage(): string {
return makeExpiredMessage(
this.field.expirationData.expirationDate,
// @ts-expect-error I did not succeed in getting i18nService.translationLocale so I fallback to a private property
{ lang: this.i18nService.systemLanguage }
);
}

private getExpiresInMessage(): string {
return makeExpiresInMessage(
this.field.expirationData.expirationDate,
// @ts-expect-error I did not succeed in getting i18nService.translationLocale so I fallback to a private property
{ locale: this.i18nService.systemLanguage === "fr" ? fr : undefined }
{ lang: this.i18nService.systemLanguage }
);
}
}
8 changes: 4 additions & 4 deletions libs/common/src/vault/models/view/field.view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ export class FieldView implements View {
value: string = null;
type: FieldType = null;
// Cozy customization
id: string = null;
parentId: string = null;
id?: string = null;
parentId?: string = null;
subtype: FieldSubType = null;
cozyType: string = null;
expirationData: ExpirationDateData = null;
label: LabelData = null;
expirationData?: ExpirationDateData = null;
label?: LabelData = null;
// Cozy customization end
newField = false; // Marks if the field is new and hasn't been saved
showValue = false;
Expand Down
18 changes: 18 additions & 0 deletions libs/common/src/vault/services/cipher.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -904,8 +904,26 @@ export class CipherService implements CipherServiceAbstraction {
});
}

// Cozy customization
// We do not want to clear the cache because reconstructing the cache involves decrypting all ciphers
// which is very costly with our papers and contacts. Instead we manually update decrypted ciphers below.
//*
await this.stateService.setEncryptedCiphers(ciphers);

const decryptedCiphers = await this.stateService.getDecryptedCiphers();
if (decryptedCiphers == null) {
return;
}

const ids = typeof id === "string" ? [id] : id;
const removed = decryptedCiphers.filter((c) => !ids.includes(c.id));

await this.stateService.setDecryptedCiphers(removed);
/*/
await this.clearCache();

await this.stateService.setEncryptedCiphers(ciphers);
//*/
}

async deleteWithServer(id: string): Promise<any> {
Expand Down
56 changes: 49 additions & 7 deletions libs/cozy/contact.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { CipherType } from "@bitwarden/common/vault/enums/cipher-type";
import { CipherData } from "@bitwarden/common/vault/models/data/cipher.data";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { ContactView } from "@bitwarden/common/vault/models/view/contact.view";
import { FieldView } from "@bitwarden/common/vault/models/view/field.view";
import { IdentityView } from "@bitwarden/common/vault/models/view/identity.view";

const { getInitials } = models.contact;
Expand Down Expand Up @@ -43,8 +44,12 @@ export const convertContactToCipherData = async (
cipherView.favorite = !!cozyMetadata?.favorite;
cipherView.fields = buildFieldsFromContact(i18nService, contact);
cipherView.contact.me = contact.me;
cipherView.creationDate = new Date(cozyMetadata?.createdAt);
cipherView.revisionDate = new Date(cozyMetadata?.updatedAt);
if (cozyMetadata?.createdAt) {
cipherView.creationDate = new Date(cozyMetadata.createdAt);
}
if (cozyMetadata?.updatedAt) {
cipherView.revisionDate = new Date(cozyMetadata.updatedAt);
}

const cipherEncrypted = await cipherService.encrypt(cipherView, key);

Expand All @@ -53,22 +58,59 @@ export const convertContactToCipherData = async (
return cipherData;
};

const chooseAddress = (cipher: CipherView): FieldView => {
const homeAddress = cipher.fields.find(
(f) => f.cozyType === "address" && f.label?.label === "home"
);

if (homeAddress) {
return homeAddress;
}

const workAddress = cipher.fields.find(
(f) => f.cozyType === "address" && f.label?.label === "work"
);

if (workAddress) {
return workAddress;
}

return cipher.fields.find((f) => f.cozyType === "address");
};

const formatAddress = (cipher: CipherView, chosenAddress: FieldView): string => {
const addressNumber = cipher.fields.find(
(f) => f.parentId === chosenAddress.id && f.cozyType === "number"
)?.value;
const addressStreet = cipher.fields.find(
(f) => f.parentId === chosenAddress.id && f.cozyType === "street"
)?.value;

if (addressNumber && addressStreet) {
return `${addressNumber} ${addressStreet}`;
} else if (addressNumber) {
return addressNumber;
} else if (addressStreet) {
return addressStreet;
}

return "";
zatteo marked this conversation as resolved.
Show resolved Hide resolved
};

export const generateIdentityViewFromCipherView = (cipher: CipherView): IdentityView => {
const identity = new IdentityView();

identity.firstName = cipher.fields.find((f) => f.cozyType === "givenName")?.value;
identity.middleName = cipher.fields.find((f) => f.cozyType === "additionalName")?.value;
identity.lastName = cipher.fields.find((f) => f.cozyType === "familyName")?.value;
identity.company = cipher.fields.find((f) => f.cozyType === "company")?.value;
identity.phone = cipher.contact.primaryPhone;
identity.email = cipher.contact.primaryEmail;

const chosenAddress = cipher.fields.find((f) => f.cozyType === "address");
const chosenAddress = chooseAddress(cipher);

if (chosenAddress) {
identity.address1 =
cipher.fields.find((f) => f.parentId === chosenAddress.id && f.cozyType === "number")?.value +
" " +
cipher.fields.find((f) => f.parentId === chosenAddress.id && f.cozyType === "street")?.value;
identity.address1 = formatAddress(cipher, chosenAddress);
identity.city = cipher.fields.find(
(f) => f.parentId === chosenAddress.id && f.cozyType === "city"
)?.value;
Expand Down
14 changes: 14 additions & 0 deletions libs/cozy/contact.lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,21 @@ export const fields = [
icon: null,
type: "text",
},
{
name: "additionalName",
icon: null,
type: "text",
},
{
name: "familyName",
icon: null,
type: "text",
},
{
name: "surname",
icon: null,
type: "text",
},
],
},
{
Expand Down Expand Up @@ -158,6 +168,8 @@ const CONTACT_FIELDS_FR = {
gender: "Civilité",
givenName: "Prénom",
familyName: "Nom",
additionalName: "2e prénom",
surname: "Nom d'usage",
phone: "Téléphone",
email: "Email",
address: "Adresse",
Expand Down Expand Up @@ -188,6 +200,8 @@ const CONTACT_FIELDS_EN = {
gender: "Civility",
givenName: "Firstname",
familyName: "Lastname",
additionalName: "2nd firstname",
surname: "Name in use",
phone: "Phone",
email: "Email",
address: "Address",
Expand Down
8 changes: 6 additions & 2 deletions libs/cozy/fields.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ export const buildFieldsFromPaper = (i18nService: I18nService, paper: any): Fiel

const qualificationLabels = formatMetadataQualification(paper.metadata);
const qualificationLabel = paper.metadata.qualification.label;
const lang = i18nService.translationLocale;

// @ts-expect-error I did not succeed in getting i18nService.translationLocale so I fallback to a private property
const lang = i18nService.systemLanguage;

const f = (a: string) => {
return new Date(a).toLocaleString(lang, { year: "numeric", month: "numeric", day: "numeric" });
};
Expand Down Expand Up @@ -225,7 +228,8 @@ export const buildFieldsFromContact = (
): FieldView[] => {
const builtFields: FieldView[] = [];

const lang = i18nService.translationLocale;
// @ts-expect-error I did not succeed in getting i18nService.translationLocale so I fallback to a private property
const lang = i18nService.systemLanguage;

buildFieldsFromContactByBrowsingModels({
models: fieldsModels,
Expand Down
12 changes: 10 additions & 2 deletions libs/cozy/note.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export const convertNoteToCipherData = async (
): Promise<CipherData> => {
const { noteIllustrationUrl } = options;

const cozyMetadata = paper.cozyMetadata;

const cipherView = new CipherView();
cipherView.id = paper.id;
cipherView.name = paper.name.replace(".cozy-note", "");
Expand All @@ -75,8 +77,14 @@ export const convertNoteToCipherData = async (
cipherView.paper.qualificationLabel = paper.metadata.qualification.label;
cipherView.fields = buildFieldsFromPaper(i18nService, paper);
cipherView.fields.push(buildField(i18nService.t("content"), cipherView.paper.noteContent));
cipherView.creationDate = new Date(paper.cozyMetadata.createdAt);
cipherView.revisionDate = new Date(paper.cozyMetadata.updatedAt);
cipherView.favorite = !!paper.cozyMetadata.favorite;

if (cozyMetadata?.createdAt) {
cipherView.creationDate = new Date(cozyMetadata.createdAt);
}
if (cozyMetadata?.updatedAt) {
cipherView.revisionDate = new Date(cozyMetadata.updatedAt);
}

const cipherEncrypted = await cipherService.encrypt(cipherView, key);

Expand Down
10 changes: 8 additions & 2 deletions libs/cozy/paper.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export const convertPaperToCipherData = async (
): Promise<CipherData> => {
const { baseUrl } = options;

const cozyMetadata = paper.cozyMetadata;

const cipherView = new CipherView();
cipherView.id = paper.id;
cipherView.name = paper.name;
Expand All @@ -58,8 +60,12 @@ export const convertPaperToCipherData = async (
cipherView.paper.qualificationLabel = paper.metadata.qualification.label;
cipherView.fields = buildFieldsFromPaper(i18nService, paper);
cipherView.favorite = !!paper.cozyMetadata.favorite;
cipherView.creationDate = new Date(paper.cozyMetadata.createdAt);
cipherView.revisionDate = new Date(paper.cozyMetadata.updatedAt);
if (cozyMetadata?.createdAt) {
cipherView.creationDate = new Date(cozyMetadata.createdAt);
}
if (cozyMetadata?.updatedAt) {
cipherView.revisionDate = new Date(cozyMetadata.updatedAt);
}

const cipherEncrypted = await cipherService.encrypt(cipherView, key);

Expand Down
30 changes: 22 additions & 8 deletions libs/cozy/paperCipher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { StateService } from "@bitwarden/common/abstractions/state.service";
import { PaperType } from "@bitwarden/common/enums/paperType";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { CipherType } from "@bitwarden/common/vault/enums/cipher-type";
import { CipherData } from "@bitwarden/common/vault/models/data/cipher.data";
Expand Down Expand Up @@ -122,14 +123,27 @@ export const favoritePaperCipher = async (

const [updatePaperWithContacts] = client.hydrateDocuments("io.cozy.files", [updatedPaper]);

const cipherData = await convertPaperToCipherData(
cipherService,
i18nService,
updatePaperWithContacts,
{
baseUrl: client.getStackClient().uri,
}
);
let cipherData;

if (cipher.paper.type === PaperType.Paper) {
cipherData = await convertPaperToCipherData(
cipherService,
i18nService,
updatePaperWithContacts,
{
baseUrl: client.getStackClient().uri,
}
);
} else if (cipher.paper.type === PaperType.Note) {
cipherData = await convertNoteToCipherData(
cipherService,
i18nService,
updatePaperWithContacts,
{
noteIllustrationUrl: await fetchNoteIllustrationUrl(client),
}
);
}

await cipherService.upsert(cipherData);

Expand Down
Loading
Loading