diff --git a/packages/helpers/src/dkim/index.ts b/packages/helpers/src/dkim/index.ts index 6fdfed90..58977865 100644 --- a/packages/helpers/src/dkim/index.ts +++ b/packages/helpers/src/dkim/index.ts @@ -56,7 +56,7 @@ export async function verifyDKIMSignature( if (passed) { console.log( - `DKIM: Verification passed after applying sanitization "${passed.sanitizer}"` + `DKIM: Verification passed after applying sanitization "${passed.sanitizer}"`, ); dkimResult = passed.result; appliedSanitization = passed.sanitizer; diff --git a/packages/helpers/tests/dkim.test.ts b/packages/helpers/tests/dkim.test.ts index aa7b5533..3d9ad1c6 100644 --- a/packages/helpers/tests/dkim.test.ts +++ b/packages/helpers/tests/dkim.test.ts @@ -1,26 +1,26 @@ -import fs from "fs"; -import path from "path"; -import { verifyDKIMSignature } from "../src/dkim"; -import * as dnsOverHttp from "../src/dkim/dns-over-http"; -import * as dnsArchive from "../src/dkim/dns-archive"; +import fs from 'fs'; +import path from 'path'; +import { verifyDKIMSignature } from '../src/dkim'; +import * as dnsOverHttp from '../src/dkim/dns-over-http'; +import * as dnsArchive from '../src/dkim/dns-archive'; jest.setTimeout(10000); -describe("DKIM signature verification", () => { - it("should pass for valid email", async () => { +describe('DKIM signature verification', () => { + it('should pass for valid email', async () => { const email = fs.readFileSync( - path.join(__dirname, "test-data/email-good.eml") + path.join(__dirname, 'test-data/email-good.eml'), ); const result = await verifyDKIMSignature(email); - expect(result.signingDomain).toBe("icloud.com"); + expect(result.signingDomain).toBe('icloud.com'); expect(result.appliedSanitization).toBeFalsy(); }); - it("should fail for invalid selector", async () => { + it('should fail for invalid selector', async () => { const email = fs.readFileSync( - path.join(__dirname, "test-data/email-invalid-selector.eml") + path.join(__dirname, 'test-data/email-invalid-selector.eml'), ); expect.assertions(1); @@ -29,14 +29,14 @@ describe("DKIM signature verification", () => { await verifyDKIMSignature(email); } catch (e) { expect(e.message).toBe( - "DKIM signature verification failed for domain icloud.com. Reason: no key" + 'DKIM signature verification failed for domain icloud.com. Reason: no key', ); } }); - it("should fail for tampered body", async () => { + it('should fail for tampered body', async () => { const email = fs.readFileSync( - path.join(__dirname, "test-data/email-body-tampered.eml") + path.join(__dirname, 'test-data/email-body-tampered.eml'), ); expect.assertions(1); @@ -45,15 +45,15 @@ describe("DKIM signature verification", () => { await verifyDKIMSignature(email); } catch (e) { expect(e.message).toBe( - "DKIM signature verification failed for domain icloud.com. Reason: body hash did not verify" + 'DKIM signature verification failed for domain icloud.com. Reason: body hash did not verify', ); } }); - it("should fail for when DKIM signature is not present for domain", async () => { + it('should fail for when DKIM signature is not present for domain', async () => { // In this email From address is user@gmail.com, but the DKIM signature is only for icloud.com const email = fs.readFileSync( - path.join(__dirname, "test-data/email-invalid-domain.eml") + path.join(__dirname, 'test-data/email-invalid-domain.eml'), ); expect.assertions(1); @@ -61,14 +61,16 @@ describe("DKIM signature verification", () => { try { await verifyDKIMSignature(email); } catch (e) { - expect(e.message).toBe("DKIM signature not found for domain gmail.com"); + expect(e.message).toBe( + 'DKIM signature not found for domain gmail.com', + ); } }); - it("should be able to override domain", async () => { + it('should be able to override domain', async () => { // From address domain is icloud.com const email = fs.readFileSync( - path.join(__dirname, "test-data/email-different-domain.eml") + path.join(__dirname, 'test-data/email-different-domain.eml'), ); // Should pass with default domain @@ -79,94 +81,96 @@ describe("DKIM signature verification", () => { // different from From domain and the below check pass. expect.assertions(1); try { - await verifyDKIMSignature(email, "domain.com"); + await verifyDKIMSignature(email, 'domain.com'); } catch (e) { - expect(e.message).toBe("DKIM signature not found for domain domain.com"); + expect(e.message).toBe( + 'DKIM signature not found for domain domain.com', + ); } }); +}); - it("should fallback to ZK Email Archive if DNS over HTTP fails", async () => { - const email = fs.readFileSync( - path.join(__dirname, "test-data/email-good.eml") - ); - - // Mock resolveDNSHTTP to throw an error just for this test - const mockResolveDNSHTTP = jest - .spyOn(dnsOverHttp, "resolveDNSHTTP") - .mockRejectedValue(new Error("Failed due to mock")); - const consoleSpy = jest.spyOn(console, "log"); - await verifyDKIMSignature(email, "icloud.com", true, true); - // Check if the error was logged to ensure fallback to ZK Email Archive happened - expect(consoleSpy).toHaveBeenCalledWith( - "DNS over HTTP failed, falling back to ZK Email Archive" - ); +it("should fallback to ZK Email Archive if DNS over HTTP fails", async () => { + const email = fs.readFileSync( + path.join(__dirname, "test-data/email-good.eml") + ); - mockResolveDNSHTTP.mockRestore(); - }); + // Mock resolveDNSHTTP to throw an error just for this test + const mockResolveDNSHTTP = jest + .spyOn(dnsOverHttp, "resolveDNSHTTP") + .mockRejectedValue(new Error("Failed due to mock")); - it("should fail on DNS over HTTP failure if fallback is not enabled", async () => { - const email = fs.readFileSync( - path.join(__dirname, "test-data/email-good.eml") - ); + const consoleSpy = jest.spyOn(console, "log"); + await verifyDKIMSignature(email, "icloud.com", true, true); - // Mock resolveDNSHTTP to throw an error just for this test - const mockResolveDNSHTTP = jest - .spyOn(dnsOverHttp, "resolveDNSHTTP") - .mockRejectedValue(new Error("Failed due to mock")); + // Check if the error was logged to ensure fallback to ZK Email Archive happened + expect(consoleSpy).toHaveBeenCalledWith( + "DNS over HTTP failed, falling back to ZK Email Archive" + ); - expect.assertions(1); - try { - await verifyDKIMSignature(email, "icloud.com", true, false); - } catch (e) { - expect(e.message).toBe( - "DKIM signature verification failed for domain icloud.com. Reason: DNS failure: Failed due to mock" - ); - } - mockResolveDNSHTTP.mockRestore(); - }); + mockResolveDNSHTTP.mockRestore(); +}); - it("should fail if both DNS over HTTP and ZK Email Archive fail", async () => { - const email = fs.readFileSync( - path.join(__dirname, "test-data/email-good.eml") +it("should fail on DNS over HTTP failure if fallback is not enabled", async () => { + const email = fs.readFileSync( + path.join(__dirname, "test-data/email-good.eml") + ); + + // Mock resolveDNSHTTP to throw an error just for this test + const mockResolveDNSHTTP = jest + .spyOn(dnsOverHttp, "resolveDNSHTTP") + .mockRejectedValue(new Error("Failed due to mock")); + + expect.assertions(1); + try { + await verifyDKIMSignature(email, "icloud.com", true, false); + } catch (e) { + expect(e.message).toBe( + "DKIM signature verification failed for domain icloud.com. Reason: DNS failure: Failed due to mock" ); + } + mockResolveDNSHTTP.mockRestore(); +}); - const mockResolveDNSHTTP = jest - .spyOn(dnsOverHttp, "resolveDNSHTTP") - .mockRejectedValue(new Error("Failed due to mock")); - - const mockResolveDNSFromZKEmailArchive = jest - .spyOn(dnsArchive, "resolveDNSFromZKEmailArchive") - .mockRejectedValue(new Error("Failed due to mock")); - - expect.assertions(1); - try { - await verifyDKIMSignature(email, "icloud.com", true, false); - } catch (e) { - expect(e.message).toBe( - "DKIM signature verification failed for domain icloud.com. Reason: DNS failure: Failed due to mock" - ); - } +it("should fail if both DNS over HTTP and ZK Email Archive fail", async () => { + const email = fs.readFileSync( + path.join(__dirname, "test-data/email-good.eml") + ); + + const mockResolveDNSHTTP = jest + .spyOn(dnsOverHttp, "resolveDNSHTTP") + .mockRejectedValue(new Error("Failed due to mock")); + + const mockResolveDNSFromZKEmailArchive = jest + .spyOn(dnsArchive, "resolveDNSFromZKEmailArchive") + .mockRejectedValue(new Error("Failed due to mock")); + + expect.assertions(1); + try { + await verifyDKIMSignature(email, "icloud.com", true, false); + } catch (e) { + expect(e.message).toBe( + "DKIM signature verification failed for domain icloud.com. Reason: DNS failure: Failed due to mock" + ); + } - mockResolveDNSHTTP.mockRestore(); - mockResolveDNSFromZKEmailArchive.mockRestore(); - }); + mockResolveDNSHTTP.mockRestore(); + mockResolveDNSFromZKEmailArchive.mockRestore(); }); -describe("DKIM with sanitization", () => { - it("should pass after removing label from Subject", async () => { +describe('DKIM with sanitization', () => { + it('should pass after removing label from Subject', async () => { const email = fs.readFileSync( - path.join(__dirname, "test-data/email-good.eml") + path.join(__dirname, 'test-data/email-good.eml'), ); // Add a label to the subject - const tamperedEmail = email - .toString() - .replace("Subject: ", "Subject: [EmailListABC]"); + const tamperedEmail = email.toString().replace('Subject: ', 'Subject: [EmailListABC]'); const result = await verifyDKIMSignature(tamperedEmail); - expect(result.appliedSanitization).toBe("removeLabels"); + expect(result.appliedSanitization).toBe('removeLabels'); }); -}); +}); \ No newline at end of file