Skip to content
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "internxt-crypto",
"version": "1.5.0",
"version": "1.6.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"module": "dist/index.js",
Expand Down
19 changes: 17 additions & 2 deletions src/email-crypto/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,18 @@ export async function encryptEmailWithKey(
): Promise<EmailEncrypted> {
try {
const text = UTF8ToUint8(email.text);
const preview = UTF8ToUint8(email.preview);

const encryptedText = await encryptSymmetrically(encryptionKey, text, aux);
const encText = uint8ArrayToBase64(encryptedText);
return { encText };

const encryptedPreview = await encryptSymmetrically(encryptionKey, preview, aux);
const encPreview = uint8ArrayToBase64(encryptedPreview);

const encryptedAttachmentsSessionKey = await encryptSymmetrically(encryptionKey, email.attachmentsSessionKey, aux);
const encAttachmentsSessionKey = uint8ArrayToBase64(encryptedAttachmentsSessionKey);

return { encText, encPreview, encAttachmentsSessionKey };
} catch (error) {
throw new EmailSymmetricEncryptionError(error instanceof Error ? error.message : String(error));
}
Expand All @@ -83,7 +91,14 @@ export async function decryptEmail(
const textArray = await decryptSymmetrically(encryptionKey, encText, aux);
const text = uint8ToUTF8(textArray);

return { text };
const encPreview = base64ToUint8Array(encEmail.encPreview);
const previewArray = await decryptSymmetrically(encryptionKey, encPreview, aux);
const preview = uint8ToUTF8(previewArray);

const encAttachementSessionKey = base64ToUint8Array(encEmail.encAttachmentsSessionKey);
const attachmentsSessionKey = await decryptSymmetrically(encryptionKey, encAttachementSessionKey, aux);

return { text, preview, attachmentsSessionKey };
} catch (error) {
throw new EmailSymmetricDecryptionError(error instanceof Error ? error.message : String(error));
}
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ export type PwdProtectedKey = {

export type EmailEncrypted = {
encText: string;
encPreview: string;
encAttachmentsSessionKey: string;
};

export type EmailAndSubjectEncrypted = EmailEncrypted & {
Expand All @@ -56,6 +58,8 @@ export type EmailAndSubjectEncrypted = EmailEncrypted & {

export type Email = {
text: string;
preview: string;
attachmentsSessionKey: Uint8Array;
};

export type EmailAndSubject = Email & {
Expand Down
4 changes: 4 additions & 0 deletions tests/email-crypto/core.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@
describe('Test email crypto functions', () => {
const email: Email = {
text: 'test email',
preview: 'email preview',
attachmentsSessionKey: new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]),
};

const emailAndSubject: EmailAndSubject = {
text: 'test email text',
subject: 'test email subject',
preview: 'email preview',
attachmentsSessionKey: new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]),
};

const aux = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
Expand All @@ -46,7 +50,7 @@
await expect(decryptEmail(encEmail, encryptionKey, badAux)).rejects.toThrow(EmailSymmetricDecryptionError);
});

it('should throw an error if decryption fails', async () => {

Check warning on line 53 in tests/email-crypto/core.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this test title to make it unique within the suite.

See more on https://sonarcloud.io/project/issues?id=internxt_crypto&issues=AZ9l3Cs8gF2-R616f7If&open=AZ9l3Cs8gF2-R616f7If&pullRequest=65
const { encEmail, encryptionKey } = await encryptEmailAndSubject(emailAndSubject, aux);
const badEncryptionKey = await genSymmetricKey();
await expect(decryptEmailAndSubject(encEmail, badEncryptionKey, aux)).rejects.toThrow(
Expand All @@ -70,7 +74,7 @@
it('should derive symmetric key for database encryption', async () => {
const mnemonic = genMnemonic();
const key = await deriveDatabaseKey(mnemonic);
expect(key.length).toBe(AES_KEY_BYTE_LENGTH);

Check warning on line 77 in tests/email-crypto/core.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer "expect(key).toHaveLength(AES_KEY_BYTE_LENGTH)" over this generic assertion for better reporting; it works on any object with a numeric length property.

See more on https://sonarcloud.io/project/issues?id=internxt_crypto&issues=AZ9l3Cs8gF2-R616f7Ig&open=AZ9l3Cs8gF2-R616f7Ig&pullRequest=65
const key2 = await deriveDatabaseKey(mnemonic);
expect(key2).toStrictEqual(key);
});
Expand All @@ -78,16 +82,16 @@
it('should derive symmetric key for email draft encryption', async () => {
const mnemonic = genMnemonic();
const key = await deriveEmailDraftKey(mnemonic);
expect(key.length).toBe(AES_KEY_BYTE_LENGTH);

Check warning on line 85 in tests/email-crypto/core.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer "expect(key).toHaveLength(AES_KEY_BYTE_LENGTH)" over this generic assertion for better reporting; it works on any object with a numeric length property.

See more on https://sonarcloud.io/project/issues?id=internxt_crypto&issues=AZ9l3Cs8gF2-R616f7Ih&open=AZ9l3Cs8gF2-R616f7Ih&pullRequest=65
const key2 = await deriveEmailDraftKey(mnemonic);
expect(key2).toStrictEqual(key);
});

it('should derive symmetric key for email draft encryption', async () => {

Check warning on line 90 in tests/email-crypto/core.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this test title to make it unique within the suite.

See more on https://sonarcloud.io/project/issues?id=internxt_crypto&issues=AZ9l3Cs8gF2-R616f7Ii&open=AZ9l3Cs8gF2-R616f7Ii&pullRequest=65
const mnemonic = genMnemonic();
const keyDatabase = await deriveDatabaseKey(mnemonic);
const keyDraft = await deriveEmailDraftKey(mnemonic);
expect(keyDatabase.length).toBe(keyDraft.length);

Check warning on line 94 in tests/email-crypto/core.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer "expect(keyDatabase).toHaveLength(keyDraft.length)" over this generic assertion for better reporting; it works on any object with a numeric length property.

See more on https://sonarcloud.io/project/issues?id=internxt_crypto&issues=AZ9l3Cs8gF2-R616f7Ij&open=AZ9l3Cs8gF2-R616f7Ij&pullRequest=65
expect(keyDraft).not.toStrictEqual(keyDatabase);
});
});
8 changes: 8 additions & 0 deletions tests/email-crypto/hybridEmail.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@
describe('Test email crypto functions', async () => {
const email: Email = {
text: 'test email text',
preview: 'Hi Bib,',
attachmentsSessionKey: new Uint8Array([1, 2, 3, 4]),
};

const emailAndSubject: EmailAndSubject = {
text: 'test email text',
subject: 'test email subject',
preview: 'Hi Bib,',
attachmentsSessionKey: new Uint8Array([1, 2, 3, 4]),
};

const { secretKey: alicePrivateKeys, publicKey: alicePublicKeys } = await generateEmailKeys();
Expand Down Expand Up @@ -90,6 +94,8 @@
encryptedKey: encKey,
encEmail: {
encText: 'mock encrypted text',
encPreview: 'mock encryped preview',
encAttachmentsSessionKey: 'mock encrypted attachement session key',
},
};

Expand All @@ -98,6 +104,8 @@
encEmail: {
encText: 'mock encrypted text',
encSubject: 'mock encrypted subject',
encPreview: 'mock encryped preview',
encAttachmentsSessionKey: 'mock encrypted attachement session key',
},
};

Expand All @@ -114,7 +122,7 @@
aliceWithPublicKeys,
]);

expect(encryptedEmail.length).toBe(2);

Check warning on line 125 in tests/email-crypto/hybridEmail.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer "expect(encryptedEmail).toHaveLength(2)" over this generic assertion for better reporting; it works on any object with a numeric length property.

See more on https://sonarcloud.io/project/issues?id=internxt_crypto&issues=AZ9l3Cq8gF2-R616f7Id&open=AZ9l3Cq8gF2-R616f7Id&pullRequest=65
expect(encryptedEmail[0].encEmail).toBe(encryptedEmail[1].encEmail);
});

Expand All @@ -124,7 +132,7 @@
aliceWithPublicKeys,
]);

expect(encryptedEmail.length).toBe(2);

Check warning on line 135 in tests/email-crypto/hybridEmail.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer "expect(encryptedEmail).toHaveLength(2)" over this generic assertion for better reporting; it works on any object with a numeric length property.

See more on https://sonarcloud.io/project/issues?id=internxt_crypto&issues=AZ9l3Cq8gF2-R616f7Ie&open=AZ9l3Cq8gF2-R616f7Ie&pullRequest=65
expect(encryptedEmail[0].encEmail).toBe(encryptedEmail[1].encEmail);

const emailDecryptedByBob = await decryptEmailAndSubjectHybrid(encryptedEmail[0], bobPrivateKeys);
Expand Down
4 changes: 4 additions & 0 deletions tests/email-crypto/pwdProtectedEmail.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ import { Email, EmailAndSubject, PwdProtectedEmail, PwdProtectedEmailAndSubject
describe('Test email crypto functions', () => {
const email: Email = {
text: 'Hi Bob, This is a test message. -Alice.',
preview: 'Hi Bib,',
attachmentsSessionKey: new Uint8Array([1, 2, 3, 4]),
};

const emailAndSubject: EmailAndSubject = {
text: 'Hi Bob, This is a test message. -Alice.',
subject: 'test subject',
preview: 'Hi Bib,',
attachmentsSessionKey: new Uint8Array([1, 2, 3, 4]),
};

const sharedSecret = 'test shared secret';
Expand Down
4 changes: 4 additions & 0 deletions tests/email-crypto/pwdProtectedEmailCoreErrors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ describe('Test email crypto functions', () => {

const email: Email = {
text: 'Hi Bob, This is a test message. -Alice.',
preview: 'Hi Bib,',
attachmentsSessionKey: new Uint8Array([1, 2, 3, 4]),
};

const emailAndSubject: EmailAndSubject = {
text: 'Hi Bob, This is a test message. -Alice.',
subject: 'test subject',
preview: 'Hi Bib,',
attachmentsSessionKey: new Uint8Array([1, 2, 3, 4]),
};

const sharedSecret = 'test shared secret';
Expand Down
4 changes: 4 additions & 0 deletions tests/email-crypto/pwdProtectedEmailNobleErrors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,15 @@ describe('Test email crypto functions', () => {

const email: Email = {
text: 'Hi Bob, This is a test message. -Alice.',
preview: 'Hi Bib,',
attachmentsSessionKey: new Uint8Array([1, 2, 3, 4]),
};

const emailAndSubject: EmailAndSubject = {
text: 'Hi Bob, This is a test message. -Alice.',
subject: 'test subject',
preview: 'Hi Bib,',
attachmentsSessionKey: new Uint8Array([1, 2, 3, 4]),
};

const sharedSecret = 'test shared secret';
Expand Down
Loading