@vaultsandbox/client 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +190 -21
- package/README.md +3 -3
- package/dist/client.d.ts +11 -3
- package/dist/client.js +83 -30
- package/dist/client.js.map +1 -1
- package/dist/crypto/decrypt.js +12 -4
- package/dist/crypto/decrypt.js.map +1 -1
- package/dist/crypto/signature.js +3 -1
- package/dist/crypto/signature.js.map +1 -1
- package/dist/email.d.ts +2 -2
- package/dist/email.js +25 -12
- package/dist/email.js.map +1 -1
- package/dist/http/api-client.d.ts +4 -2
- package/dist/http/api-client.js +17 -3
- package/dist/http/api-client.js.map +1 -1
- package/dist/inbox.d.ts +69 -3
- package/dist/inbox.js +142 -14
- package/dist/inbox.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/strategies/delivery-strategy.d.ts +7 -5
- package/dist/strategies/polling-strategy.d.ts +5 -5
- package/dist/strategies/polling-strategy.js +46 -21
- package/dist/strategies/polling-strategy.js.map +1 -1
- package/dist/strategies/sse-strategy.d.ts +8 -3
- package/dist/strategies/sse-strategy.js +112 -15
- package/dist/strategies/sse-strategy.js.map +1 -1
- package/dist/sync/inbox-sync.d.ts +31 -0
- package/dist/sync/inbox-sync.js +52 -0
- package/dist/sync/inbox-sync.js.map +1 -0
- package/dist/types/index.d.ts +64 -17
- package/dist/types/index.js.map +1 -1
- package/dist/utils/email-utils.d.ts +14 -3
- package/dist/utils/email-utils.js +41 -1
- package/dist/utils/email-utils.js.map +1 -1
- package/dist/utils/hash.d.ts +15 -0
- package/dist/utils/hash.js +31 -0
- package/dist/utils/hash.js.map +1 -0
- package/package.json +5 -5
package/dist/crypto/signature.js
CHANGED
|
@@ -54,7 +54,9 @@ export function verifySignature(encryptedData) {
|
|
|
54
54
|
if (error instanceof SignatureVerificationError) {
|
|
55
55
|
throw error;
|
|
56
56
|
}
|
|
57
|
-
|
|
57
|
+
/* istanbul ignore next - defensive for non-Error exceptions */
|
|
58
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
59
|
+
throw new SignatureVerificationError(`Signature verification error: ${message}`);
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signature.js","sourceRoot":"","sources":["../../src/crypto/signature.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAErE;;GAEG;AACH,SAAS,oBAAoB,CAAC,IAA6D;IACzF,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;AAC5D,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CACtB,OAAe,EACf,eAAuB,EACvB,KAAiB,EACjB,KAAiB,EACjB,GAAe,EACf,UAAsB,EACtB,WAAuB,EACvB,OAAe;IAEf,MAAM,YAAY,GAAG,IAAI,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAC5D,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvD,OAAO,aAAa,CAAC,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AAC1G,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,aAA4B;IAC1D,IAAI,CAAC;QACH,2BAA2B;QAC3B,MAAM,SAAS,GAAG,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,UAAU,GAAG,aAAa,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAClD,MAAM,eAAe,GAAG,aAAa,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAChE,MAAM,WAAW,GAAG,aAAa,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;QAE/D,sDAAsD;QACtD,MAAM,eAAe,GAAG,oBAAoB,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,UAAU,GAAG,eAAe,CAChC,aAAa,CAAC,CAAC,EACf,eAAe,EACf,KAAK,EACL,UAAU,EACV,QAAQ,EACR,eAAe,EACf,WAAW,EACX,YAAY,CACb,CAAC;QAEF,0BAA0B;QAC1B,yEAAyE;QACzE,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAC7B,eAAe,CAAC,SAAS,CAAC,EAC1B,eAAe,CAAC,UAAU,CAAC,EAC3B,eAAe,CAAC,WAAW,CAAC,CAC7B,CAAC;QAEF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,0BAA0B,CAAC,uDAAuD,CAAC,CAAC;QAChG,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,0BAA0B,EAAE,CAAC;YAChD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,
|
|
1
|
+
{"version":3,"file":"signature.js","sourceRoot":"","sources":["../../src/crypto/signature.ts"],"names":[],"mappings":"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"}
|
package/dist/email.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export declare class Email implements IEmail {
|
|
|
41
41
|
* @internal
|
|
42
42
|
* Do not construct this class directly.
|
|
43
43
|
*/
|
|
44
|
-
constructor(emailData: EmailData, metadata: DecryptedMetadata, parsed: DecryptedParsed | null, emailAddress: string, apiClient: ApiClient, keypair: Keypair);
|
|
44
|
+
constructor(emailData: EmailData, metadata: DecryptedMetadata, parsed: DecryptedParsed | null, emailAddress: string, apiClient: ApiClient, keypair: Keypair | null);
|
|
45
45
|
/**
|
|
46
46
|
* Marks this email as read.
|
|
47
47
|
*
|
|
@@ -55,7 +55,7 @@ export declare class Email implements IEmail {
|
|
|
55
55
|
*/
|
|
56
56
|
delete(): Promise<void>;
|
|
57
57
|
/**
|
|
58
|
-
* Fetches the raw
|
|
58
|
+
* Fetches the raw source of the email (decrypts if encrypted).
|
|
59
59
|
*
|
|
60
60
|
* @returns A promise that resolves to the raw email data.
|
|
61
61
|
*/
|
package/dist/email.js
CHANGED
|
@@ -37,28 +37,28 @@ class AuthResults {
|
|
|
37
37
|
validate() {
|
|
38
38
|
debug('Validating email authentication results');
|
|
39
39
|
const failures = [];
|
|
40
|
-
// Check SPF
|
|
41
|
-
const spfPassed = this.spf?.result === 'pass';
|
|
40
|
+
// Check SPF (skipped is treated as passing - not a failure)
|
|
41
|
+
const spfPassed = this.spf?.result === 'pass' || this.spf?.result === 'skipped';
|
|
42
42
|
if (this.spf && !spfPassed) {
|
|
43
43
|
failures.push(`SPF check failed: ${this.spf.result}${this.spf.domain ? ` (domain: ${this.spf.domain})` : ''}`);
|
|
44
44
|
}
|
|
45
|
-
// Check DKIM (at least one signature must pass)
|
|
46
|
-
const dkimPassed = this.dkim?.some((d) => d.result === 'pass') ?? false;
|
|
45
|
+
// Check DKIM (at least one signature must pass or be skipped)
|
|
46
|
+
const dkimPassed = this.dkim?.some((d) => d.result === 'pass' || d.result === 'skipped') ?? false;
|
|
47
47
|
if (this.dkim && this.dkim.length > 0 && !dkimPassed) {
|
|
48
48
|
const failedDomains = this.dkim
|
|
49
|
-
.filter((d) => d.result !== 'pass')
|
|
49
|
+
.filter((d) => d.result !== 'pass' && d.result !== 'skipped')
|
|
50
50
|
.map((d) => d.domain)
|
|
51
51
|
.filter(Boolean)
|
|
52
52
|
.join(', ');
|
|
53
53
|
failures.push(`DKIM signature failed${failedDomains ? `: ${failedDomains}` : ''}`);
|
|
54
54
|
}
|
|
55
|
-
// Check DMARC
|
|
56
|
-
const dmarcPassed = this.dmarc?.result === 'pass';
|
|
55
|
+
// Check DMARC (skipped is treated as passing - not a failure)
|
|
56
|
+
const dmarcPassed = this.dmarc?.result === 'pass' || this.dmarc?.result === 'skipped';
|
|
57
57
|
if (this.dmarc && !dmarcPassed) {
|
|
58
58
|
failures.push(`DMARC policy: ${this.dmarc.result}${this.dmarc.policy ? ` (policy: ${this.dmarc.policy})` : ''}`);
|
|
59
59
|
}
|
|
60
|
-
// Check Reverse DNS -
|
|
61
|
-
const reverseDnsPassed = this.reverseDns?.
|
|
60
|
+
// Check Reverse DNS (skipped is treated as passing - not a failure)
|
|
61
|
+
const reverseDnsPassed = this.reverseDns?.result === 'pass' || this.reverseDns?.result === 'skipped';
|
|
62
62
|
if (this.reverseDns && !reverseDnsPassed) {
|
|
63
63
|
failures.push(`Reverse DNS check failed${this.reverseDns.hostname ? ` (hostname: ${this.reverseDns.hostname})` : ''}`);
|
|
64
64
|
}
|
|
@@ -123,6 +123,7 @@ export class Email {
|
|
|
123
123
|
this.emailAddress = emailAddress;
|
|
124
124
|
this.apiClient = apiClient;
|
|
125
125
|
this.keypair = keypair;
|
|
126
|
+
// istanbul ignore next -- this.to is always an array per line 166, else branch is defensive
|
|
126
127
|
debug('Creating email %s from %s to %s', this.id, this.from, Array.isArray(this.to) ? this.to.join(', ') : this.to);
|
|
127
128
|
// If parsed content is available, use it
|
|
128
129
|
if (parsed) {
|
|
@@ -171,15 +172,27 @@ export class Email {
|
|
|
171
172
|
debug('Successfully deleted email %s', this.id);
|
|
172
173
|
}
|
|
173
174
|
/**
|
|
174
|
-
* Fetches the raw
|
|
175
|
+
* Fetches the raw source of the email (decrypts if encrypted).
|
|
175
176
|
*
|
|
176
177
|
* @returns A promise that resolves to the raw email data.
|
|
177
178
|
*/
|
|
178
179
|
async getRaw() {
|
|
179
180
|
debug('Fetching raw content for email %s', this.id);
|
|
180
181
|
const rawEmailData = await this.apiClient.getRawEmail(this.emailAddress, this.id);
|
|
181
|
-
|
|
182
|
-
|
|
182
|
+
let raw;
|
|
183
|
+
/* istanbul ignore else - defensive for invalid raw email response */
|
|
184
|
+
if (rawEmailData.encryptedRaw) {
|
|
185
|
+
// Encrypted inbox - decrypt the raw content
|
|
186
|
+
raw = await decryptRaw(rawEmailData.encryptedRaw, this.keypair);
|
|
187
|
+
}
|
|
188
|
+
else if (rawEmailData.raw) {
|
|
189
|
+
// Plain inbox - decode base64
|
|
190
|
+
raw = Buffer.from(rawEmailData.raw, 'base64').toString('utf-8');
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
throw new Error('Invalid raw email data: neither encryptedRaw nor raw field present');
|
|
194
|
+
}
|
|
195
|
+
debug('Successfully fetched and processed raw content for email %s (%d characters)', this.id, raw.length);
|
|
183
196
|
return { id: rawEmailData.id, raw };
|
|
184
197
|
}
|
|
185
198
|
}
|
package/dist/email.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email.js","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AAEH,OAAO,WAAW,MAAM,OAAO,CAAC;AAkBhC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,KAAK,GAAG,WAAW,CAAC,oBAAoB,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW;IACf,2DAA2D;IAC3D,GAAG,CAAa;IAChB,wEAAwE;IACxE,IAAI,CAAgB;IACpB,qGAAqG;IACrG,KAAK,CAAe;IACpB,yCAAyC;IACzC,UAAU,CAAoB;IAE9B;;OAEG;IACH,YAAY,IAAqB;QAC/B,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAElC,KAAK,CACH,uEAAuE,EACvE,IAAI,CAAC,GAAG,EACR,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,UAAU,CAChB,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACN,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,
|
|
1
|
+
{"version":3,"file":"email.js","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AAEH,OAAO,WAAW,MAAM,OAAO,CAAC;AAkBhC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,KAAK,GAAG,WAAW,CAAC,oBAAoB,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW;IACf,2DAA2D;IAC3D,GAAG,CAAa;IAChB,wEAAwE;IACxE,IAAI,CAAgB;IACpB,qGAAqG;IACrG,KAAK,CAAe;IACpB,yCAAyC;IACzC,UAAU,CAAoB;IAE9B;;OAEG;IACH,YAAY,IAAqB;QAC/B,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAElC,KAAK,CACH,uEAAuE,EACvE,IAAI,CAAC,GAAG,EACR,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,UAAU,CAChB,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACN,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,4DAA4D;QAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;QAChF,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACjH,CAAC;QAED,8DAA8D;QAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,IAAI,KAAK,CAAC;QAClG,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI;iBAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;iBAC5D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;iBACpB,MAAM,CAAC,OAAO,CAAC;iBACf,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,QAAQ,CAAC,IAAI,CAAC,wBAAwB,aAAa,CAAC,CAAC,CAAC,KAAK,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrF,CAAC;QAED,8DAA8D;QAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;QACtF,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;YAC/B,QAAQ,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnH,CAAC;QAED,oEAAoE;QACpE,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE,MAAM,KAAK,SAAS,CAAC;QACrG,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACzC,QAAQ,CAAC,IAAI,CACX,2BAA2B,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,UAAU,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACxG,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG;YACjB,MAAM,EAAE,SAAS,IAAI,UAAU,IAAI,WAAW;YAC9C,SAAS;YACT,UAAU;YACV,WAAW;YACX,gBAAgB;YAChB,QAAQ;SACT,CAAC;QAEF,KAAK,CAAC,sCAAsC,EAAE,UAAU,CAAC,CAAC;QAC1D,OAAO,UAAU,CAAC;IACpB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,KAAK;IAChB,2CAA2C;IAClC,EAAE,CAAS;IACpB,kCAAkC;IACzB,IAAI,CAAS;IACtB,6CAA6C;IACpC,EAAE,CAAW;IACtB,gCAAgC;IACvB,OAAO,CAAS;IACzB,gDAAgD;IACvC,UAAU,CAAO;IAC1B,4DAA4D;IACnD,MAAM,CAAU;IACzB,uEAAuE;IAC9D,IAAI,CAAgB;IAC7B,iEAAiE;IACxD,IAAI,CAAgB;IAC7B,kDAAkD;IACzC,WAAW,CAAmB;IACvC,2DAA2D;IAClD,KAAK,CAAW;IACzB,gDAAgD;IACvC,OAAO,CAA0B;IAC1C,6DAA6D;IACpD,WAAW,CAAe;IACnC,oDAAoD;IAC3C,QAAQ,CAA0B;IAEnC,YAAY,CAAS;IACrB,SAAS,CAAY;IACrB,OAAO,CAAiB;IAEhC;;;OAGG;IACH,YACE,SAAoB,EACpB,QAA2B,EAC3B,MAA8B,EAC9B,YAAoB,EACpB,SAAoB,EACpB,OAAuB;QAEvB,IAAI,CAAC,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC1B,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnF,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QAChC,MAAM,eAAe,GACnB,QAAQ,CAAC,UAAU,IAAK,SAA8C,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QAClG,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,4FAA4F;QAC5F,KAAK,CAAC,iCAAiC,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEpH,yCAAyC;QACzC,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACxB,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;YAC9B,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;YAC7D,KAAK,CACH,sEAAsE,EACtE,IAAI,CAAC,EAAE,EACP,IAAI,CAAC,WAAW,CAAC,MAAM,EACvB,IAAI,CAAC,KAAK,CAAC,MAAM,CAClB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,sDAAsD;YACtD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;YAClB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;YACvC,KAAK,CAAC,qCAAqC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QACxD,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,UAAU;QACd,KAAK,CAAC,0BAA0B,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3C,MAAM,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QACjE,6FAA6F;QAC7F,6FAA6F;QAC7F,gGAAgG;QAC/F,IAAmD,CAAC,MAAM,GAAG,IAAI,CAAC;QACnE,KAAK,CAAC,sCAAsC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM;QACV,KAAK,CAAC,mBAAmB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7D,KAAK,CAAC,+BAA+B,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM;QACV,KAAK,CAAC,mCAAmC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QACpD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAClF,IAAI,GAAW,CAAC;QAEhB,qEAAqE;QACrE,IAAI,YAAY,CAAC,YAAY,EAAE,CAAC;YAC9B,4CAA4C;YAC5C,GAAG,GAAG,MAAM,UAAU,CAAC,YAAY,CAAC,YAAY,EAAE,IAAI,CAAC,OAAQ,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,YAAY,CAAC,GAAG,EAAE,CAAC;YAC5B,8BAA8B;YAC9B,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACxF,CAAC;QAED,KAAK,CAAC,6EAA6E,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1G,OAAO,EAAE,EAAE,EAAE,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC;IACtC,CAAC;CACF"}
|
|
@@ -44,14 +44,16 @@ export declare class ApiClient {
|
|
|
44
44
|
checkKey(): Promise<boolean>;
|
|
45
45
|
/**
|
|
46
46
|
* Creates a new temporary inbox on the server.
|
|
47
|
-
* @param publicKey - The client's KEM public key for encrypted communication
|
|
47
|
+
* @param publicKey - The client's KEM public key for encrypted communication (required for encrypted inboxes)
|
|
48
48
|
* @param ttl - Optional time-to-live in seconds for the inbox
|
|
49
49
|
* @param emailAddress - Optional desired email address or domain
|
|
50
|
+
* @param emailAuth - Optional flag to enable email authentication checks
|
|
51
|
+
* @param encryption - Optional encryption preference ('encrypted' or 'plain')
|
|
50
52
|
* @returns Promise resolving to the created inbox data including email address
|
|
51
53
|
* @throws {NetworkError} If network communication fails
|
|
52
54
|
* @throws {ApiError} If the server returns an error response
|
|
53
55
|
*/
|
|
54
|
-
createInbox(publicKey
|
|
56
|
+
createInbox(publicKey?: string, ttl?: number, emailAddress?: string, emailAuth?: boolean, encryption?: 'encrypted' | 'plain'): Promise<InboxData>;
|
|
55
57
|
/**
|
|
56
58
|
* Deletes a specific inbox and all its emails.
|
|
57
59
|
* @param emailAddress - The email address of the inbox to delete
|
package/dist/http/api-client.js
CHANGED
|
@@ -70,6 +70,7 @@ export class ApiClient {
|
|
|
70
70
|
return new NetworkError(error.message || 'Network error occurred');
|
|
71
71
|
}
|
|
72
72
|
const status = error.response.status;
|
|
73
|
+
/* istanbul ignore next - defensive fallback when server doesn't return error message */
|
|
73
74
|
const message = error.response.data?.error || error.message;
|
|
74
75
|
if (status === 404) {
|
|
75
76
|
if (message.toLowerCase().includes('inbox')) {
|
|
@@ -105,21 +106,32 @@ export class ApiClient {
|
|
|
105
106
|
// ===== Inbox Management =====
|
|
106
107
|
/**
|
|
107
108
|
* Creates a new temporary inbox on the server.
|
|
108
|
-
* @param publicKey - The client's KEM public key for encrypted communication
|
|
109
|
+
* @param publicKey - The client's KEM public key for encrypted communication (required for encrypted inboxes)
|
|
109
110
|
* @param ttl - Optional time-to-live in seconds for the inbox
|
|
110
111
|
* @param emailAddress - Optional desired email address or domain
|
|
112
|
+
* @param emailAuth - Optional flag to enable email authentication checks
|
|
113
|
+
* @param encryption - Optional encryption preference ('encrypted' or 'plain')
|
|
111
114
|
* @returns Promise resolving to the created inbox data including email address
|
|
112
115
|
* @throws {NetworkError} If network communication fails
|
|
113
116
|
* @throws {ApiError} If the server returns an error response
|
|
114
117
|
*/
|
|
115
|
-
async createInbox(publicKey, ttl, emailAddress) {
|
|
116
|
-
const payload = {
|
|
118
|
+
async createInbox(publicKey, ttl, emailAddress, emailAuth, encryption) {
|
|
119
|
+
const payload = {};
|
|
120
|
+
if (publicKey !== undefined && publicKey !== null) {
|
|
121
|
+
payload.clientKemPk = publicKey;
|
|
122
|
+
}
|
|
117
123
|
if (ttl !== undefined && ttl !== null) {
|
|
118
124
|
payload.ttl = ttl;
|
|
119
125
|
}
|
|
120
126
|
if (emailAddress !== undefined && emailAddress !== null) {
|
|
121
127
|
payload.emailAddress = emailAddress;
|
|
122
128
|
}
|
|
129
|
+
if (emailAuth !== undefined) {
|
|
130
|
+
payload.emailAuth = emailAuth;
|
|
131
|
+
}
|
|
132
|
+
if (encryption !== undefined) {
|
|
133
|
+
payload.encryption = encryption;
|
|
134
|
+
}
|
|
123
135
|
const response = await this.client.post('/api/inboxes', payload);
|
|
124
136
|
return response.data;
|
|
125
137
|
}
|
|
@@ -140,6 +152,7 @@ export class ApiClient {
|
|
|
140
152
|
* @throws {NetworkError} If network communication fails
|
|
141
153
|
* @throws {ApiError} If the server returns an error response
|
|
142
154
|
*/
|
|
155
|
+
/* istanbul ignore next 4 - destructive operation, not safe to test against real server */
|
|
143
156
|
async deleteAllInboxes() {
|
|
144
157
|
const response = await this.client.delete('/api/inboxes');
|
|
145
158
|
return response.data;
|
|
@@ -166,6 +179,7 @@ export class ApiClient {
|
|
|
166
179
|
* @throws {InboxNotFoundError} If the inbox does not exist
|
|
167
180
|
* @throws {ApiError} If the server returns an error response
|
|
168
181
|
*/
|
|
182
|
+
/* istanbul ignore next - false positive on default parameter value */
|
|
169
183
|
async listEmails(emailAddress, includeContent = false) {
|
|
170
184
|
const query = includeContent ? '?includeContent=true' : '';
|
|
171
185
|
const response = await this.client.get(`/api/inboxes/${encodeURIComponent(emailAddress)}/emails${query}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/http/api-client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/http/api-client.ts"],"names":[],"mappings":"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"}
|
package/dist/inbox.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Inbox class - manages email retrieval and decryption for a single inbox
|
|
3
3
|
*/
|
|
4
|
-
import type { InboxData, Keypair, WaitOptions, WaitForCountOptions, SyncStatus, RawEmail, Subscription, IEmail, IEmailMetadata, ExportedInboxData } from './types/index.js';
|
|
4
|
+
import type { InboxData, Keypair, WaitOptions, WaitForCountOptions, SyncStatus, RawEmail, Subscription, IEmail, IEmailMetadata, ExportedInboxData, EmailData } from './types/index.js';
|
|
5
5
|
import type { ApiClient } from './http/api-client.js';
|
|
6
6
|
import type { DeliveryStrategy } from './strategies/delivery-strategy.js';
|
|
7
7
|
/**
|
|
@@ -17,15 +17,20 @@ export declare class Inbox {
|
|
|
17
17
|
expiresAt: Date;
|
|
18
18
|
/** A unique identifier for the inbox. */
|
|
19
19
|
readonly inboxHash: string;
|
|
20
|
+
/** Whether this inbox uses encryption. */
|
|
21
|
+
readonly encrypted: boolean;
|
|
22
|
+
/** Whether email authentication checks (SPF, DKIM, DMARC, PTR) are enabled for this inbox. */
|
|
23
|
+
readonly emailAuth: boolean;
|
|
20
24
|
private keypair;
|
|
21
25
|
private apiClient;
|
|
22
26
|
private serverPublicKey;
|
|
23
27
|
private strategy;
|
|
28
|
+
private emailCache;
|
|
24
29
|
/**
|
|
25
30
|
* @internal
|
|
26
31
|
* Do not construct this class directly. Use `VaultSandboxClient.createInbox()` instead.
|
|
27
32
|
*/
|
|
28
|
-
constructor(inboxData: InboxData, keypair: Keypair, apiClient: ApiClient, serverPublicKey: string);
|
|
33
|
+
constructor(inboxData: InboxData, keypair: Keypair | null, apiClient: ApiClient, serverPublicKey: string | null);
|
|
29
34
|
/**
|
|
30
35
|
* @internal
|
|
31
36
|
* Sets the delivery strategy for this inbox.
|
|
@@ -110,7 +115,7 @@ export declare class Inbox {
|
|
|
110
115
|
*/
|
|
111
116
|
delete(): Promise<void>;
|
|
112
117
|
/**
|
|
113
|
-
* Exports this inbox, including its key material, for backup/sharing.
|
|
118
|
+
* Exports this inbox, including its key material (for encrypted inboxes), for backup/sharing.
|
|
114
119
|
* See vaultsandbox-spec.md Section 9: Inbox Export Format
|
|
115
120
|
*/
|
|
116
121
|
export(): ExportedInboxData;
|
|
@@ -123,4 +128,65 @@ export declare class Inbox {
|
|
|
123
128
|
* @returns A promise that resolves to the sync status.
|
|
124
129
|
*/
|
|
125
130
|
getSyncStatus(): Promise<SyncStatus>;
|
|
131
|
+
/**
|
|
132
|
+
* Gets all email IDs currently in the local cache.
|
|
133
|
+
*
|
|
134
|
+
* @returns An array of email IDs.
|
|
135
|
+
*/
|
|
136
|
+
getEmailIds(): string[];
|
|
137
|
+
/**
|
|
138
|
+
* Gets the local email cache.
|
|
139
|
+
*
|
|
140
|
+
* @returns The email cache map.
|
|
141
|
+
* @internal
|
|
142
|
+
*/
|
|
143
|
+
getEmailCache(): Map<string, EmailData>;
|
|
144
|
+
/**
|
|
145
|
+
* Adds an email to the local cache.
|
|
146
|
+
*
|
|
147
|
+
* @param email - The email data to add.
|
|
148
|
+
* @returns `true` if the email was added, `false` if it already existed.
|
|
149
|
+
*/
|
|
150
|
+
addEmail(email: EmailData): boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Removes an email from the local cache.
|
|
153
|
+
*
|
|
154
|
+
* @param emailId - The ID of the email to remove.
|
|
155
|
+
* @returns `true` if the email was removed, `false` if it didn't exist.
|
|
156
|
+
*/
|
|
157
|
+
removeEmail(emailId: string): boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Checks if an email exists in the local cache.
|
|
160
|
+
*
|
|
161
|
+
* @param emailId - The ID of the email to check.
|
|
162
|
+
* @returns `true` if the email exists, `false` otherwise.
|
|
163
|
+
*/
|
|
164
|
+
hasEmail(emailId: string): boolean;
|
|
165
|
+
/**
|
|
166
|
+
* Computes the hash of the local email cache.
|
|
167
|
+
*
|
|
168
|
+
* This hash can be compared with the server's hash to detect changes.
|
|
169
|
+
* Uses the algorithm: BASE64URL(SHA256(SORT(emailIds).join(",")))
|
|
170
|
+
*
|
|
171
|
+
* @returns The computed hash of local email IDs.
|
|
172
|
+
*/
|
|
173
|
+
computeLocalHash(): string;
|
|
174
|
+
/**
|
|
175
|
+
* Clears all emails from the local cache.
|
|
176
|
+
*/
|
|
177
|
+
clearEmailCache(): void;
|
|
178
|
+
/**
|
|
179
|
+
* Gets the keypair for this inbox.
|
|
180
|
+
*
|
|
181
|
+
* @returns The keypair, or null for plain inboxes.
|
|
182
|
+
* @internal
|
|
183
|
+
*/
|
|
184
|
+
getKeypair(): Keypair | null;
|
|
185
|
+
/**
|
|
186
|
+
* Gets the API client for this inbox.
|
|
187
|
+
*
|
|
188
|
+
* @returns The API client.
|
|
189
|
+
* @internal
|
|
190
|
+
*/
|
|
191
|
+
getApiClient(): ApiClient;
|
|
126
192
|
}
|
package/dist/inbox.js
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import createDebug from 'debug';
|
|
5
5
|
import { decryptMetadata, decryptRaw } from './crypto/decrypt.js';
|
|
6
|
-
import { decryptEmailData } from './utils/email-utils.js';
|
|
6
|
+
import { decryptEmailData, decodeBase64EmailData, isEncryptedEmailData } from './utils/email-utils.js';
|
|
7
7
|
import { toBase64Url } from './crypto/utils.js';
|
|
8
8
|
import { EXPORT_VERSION } from './crypto/constants.js';
|
|
9
|
+
import { computeEmailsHash } from './utils/hash.js';
|
|
9
10
|
import { TimeoutError, StrategyError } from './types/index.js';
|
|
10
11
|
const debug = createDebug('vaultsandbox:inbox');
|
|
11
12
|
/**
|
|
@@ -21,10 +22,15 @@ export class Inbox {
|
|
|
21
22
|
expiresAt;
|
|
22
23
|
/** A unique identifier for the inbox. */
|
|
23
24
|
inboxHash;
|
|
25
|
+
/** Whether this inbox uses encryption. */
|
|
26
|
+
encrypted;
|
|
27
|
+
/** Whether email authentication checks (SPF, DKIM, DMARC, PTR) are enabled for this inbox. */
|
|
28
|
+
emailAuth;
|
|
24
29
|
keypair;
|
|
25
30
|
apiClient;
|
|
26
31
|
serverPublicKey;
|
|
27
32
|
strategy = null;
|
|
33
|
+
emailCache = new Map();
|
|
28
34
|
/**
|
|
29
35
|
* @internal
|
|
30
36
|
* Do not construct this class directly. Use `VaultSandboxClient.createInbox()` instead.
|
|
@@ -33,10 +39,12 @@ export class Inbox {
|
|
|
33
39
|
this.emailAddress = inboxData.emailAddress;
|
|
34
40
|
this.inboxHash = inboxData.inboxHash;
|
|
35
41
|
this.expiresAt = new Date(inboxData.expiresAt);
|
|
42
|
+
this.encrypted = inboxData.encrypted;
|
|
43
|
+
this.emailAuth = inboxData.emailAuth ?? false;
|
|
36
44
|
this.keypair = keypair;
|
|
37
45
|
this.apiClient = apiClient;
|
|
38
46
|
this.serverPublicKey = serverPublicKey;
|
|
39
|
-
debug('Created inbox for %s (expires: %s)', this.emailAddress, this.expiresAt.toISOString());
|
|
47
|
+
debug('Created inbox for %s (expires: %s, encrypted: %s)', this.emailAddress, this.expiresAt.toISOString(), this.encrypted);
|
|
40
48
|
}
|
|
41
49
|
/**
|
|
42
50
|
* @internal
|
|
@@ -58,10 +66,12 @@ export class Inbox {
|
|
|
58
66
|
debug('Retrieved %d raw email data entries', emailsData.length);
|
|
59
67
|
const emails = [];
|
|
60
68
|
for (const emailData of emailsData) {
|
|
61
|
-
const email =
|
|
69
|
+
const email = isEncryptedEmailData(emailData)
|
|
70
|
+
? await decryptEmailData(emailData, this.keypair, this.emailAddress, this.apiClient)
|
|
71
|
+
: decodeBase64EmailData(emailData, this.emailAddress, this.apiClient);
|
|
62
72
|
emails.push(email);
|
|
63
73
|
}
|
|
64
|
-
debug('Successfully
|
|
74
|
+
debug('Successfully processed %d emails for inbox %s', emails.length, this.emailAddress);
|
|
65
75
|
return emails;
|
|
66
76
|
}
|
|
67
77
|
/**
|
|
@@ -75,7 +85,15 @@ export class Inbox {
|
|
|
75
85
|
debug('Retrieved %d raw email data entries', emailsData.length);
|
|
76
86
|
const emails = [];
|
|
77
87
|
for (const emailData of emailsData) {
|
|
78
|
-
|
|
88
|
+
let metadata;
|
|
89
|
+
if (isEncryptedEmailData(emailData)) {
|
|
90
|
+
metadata = await decryptMetadata(emailData.encryptedMetadata, this.keypair);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// Plain email - decode base64 metadata
|
|
94
|
+
const metadataJson = Buffer.from(emailData.metadata, 'base64').toString('utf-8');
|
|
95
|
+
metadata = JSON.parse(metadataJson);
|
|
96
|
+
}
|
|
79
97
|
emails.push({
|
|
80
98
|
id: emailData.id,
|
|
81
99
|
from: metadata.from,
|
|
@@ -84,7 +102,7 @@ export class Inbox {
|
|
|
84
102
|
isRead: emailData.isRead,
|
|
85
103
|
});
|
|
86
104
|
}
|
|
87
|
-
debug('Successfully
|
|
105
|
+
debug('Successfully processed %d email metadata for inbox %s', emails.length, this.emailAddress);
|
|
88
106
|
return emails;
|
|
89
107
|
}
|
|
90
108
|
/**
|
|
@@ -96,8 +114,10 @@ export class Inbox {
|
|
|
96
114
|
async getEmail(emailId) {
|
|
97
115
|
debug('Retrieving email %s from inbox %s', emailId, this.emailAddress);
|
|
98
116
|
const emailData = await this.apiClient.getEmail(this.emailAddress, emailId);
|
|
99
|
-
const email =
|
|
100
|
-
|
|
117
|
+
const email = isEncryptedEmailData(emailData)
|
|
118
|
+
? await decryptEmailData(emailData, this.keypair, this.emailAddress, this.apiClient)
|
|
119
|
+
: decodeBase64EmailData(emailData, this.emailAddress, this.apiClient);
|
|
120
|
+
debug('Successfully retrieved and processed email %s', emailId);
|
|
101
121
|
return email;
|
|
102
122
|
}
|
|
103
123
|
/**
|
|
@@ -109,8 +129,18 @@ export class Inbox {
|
|
|
109
129
|
async getRawEmail(emailId) {
|
|
110
130
|
debug('Retrieving raw email %s from inbox %s', emailId, this.emailAddress);
|
|
111
131
|
const rawEmailData = await this.apiClient.getRawEmail(this.emailAddress, emailId);
|
|
112
|
-
|
|
113
|
-
|
|
132
|
+
let raw;
|
|
133
|
+
if (rawEmailData.encryptedRaw) {
|
|
134
|
+
raw = await decryptRaw(rawEmailData.encryptedRaw, this.keypair);
|
|
135
|
+
}
|
|
136
|
+
else if (rawEmailData.raw) {
|
|
137
|
+
// Plain email - decode base64
|
|
138
|
+
raw = Buffer.from(rawEmailData.raw, 'base64').toString('utf-8');
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
throw new Error('Invalid raw email data: neither encryptedRaw nor raw field present');
|
|
142
|
+
}
|
|
143
|
+
debug('Successfully retrieved and processed raw email %s (%d characters)', emailId, raw.length);
|
|
114
144
|
return { id: rawEmailData.id, raw };
|
|
115
145
|
}
|
|
116
146
|
/**
|
|
@@ -154,6 +184,7 @@ export class Inbox {
|
|
|
154
184
|
let subscription;
|
|
155
185
|
let timeoutTimer;
|
|
156
186
|
// Centralized cleanup to prevent memory leaks
|
|
187
|
+
/* istanbul ignore next 4 - defensive checks for race conditions */
|
|
157
188
|
const cleanup = () => {
|
|
158
189
|
if (timeoutTimer)
|
|
159
190
|
clearTimeout(timeoutTimer);
|
|
@@ -232,20 +263,24 @@ export class Inbox {
|
|
|
232
263
|
debug('Successfully deleted inbox %s', this.emailAddress);
|
|
233
264
|
}
|
|
234
265
|
/**
|
|
235
|
-
* Exports this inbox, including its key material, for backup/sharing.
|
|
266
|
+
* Exports this inbox, including its key material (for encrypted inboxes), for backup/sharing.
|
|
236
267
|
* See vaultsandbox-spec.md Section 9: Inbox Export Format
|
|
237
268
|
*/
|
|
238
269
|
export() {
|
|
239
|
-
debug('Exporting inbox %s
|
|
270
|
+
debug('Exporting inbox %s (encrypted: %s)', this.emailAddress, this.encrypted);
|
|
240
271
|
const exportedData = {
|
|
241
272
|
version: EXPORT_VERSION,
|
|
242
273
|
emailAddress: this.emailAddress,
|
|
243
274
|
expiresAt: this.expiresAt.toISOString(),
|
|
244
275
|
inboxHash: this.inboxHash,
|
|
245
|
-
|
|
246
|
-
secretKey: toBase64Url(this.keypair.secretKey),
|
|
276
|
+
encrypted: this.encrypted,
|
|
247
277
|
exportedAt: new Date().toISOString(),
|
|
248
278
|
};
|
|
279
|
+
// Only include keys for encrypted inboxes
|
|
280
|
+
if (this.encrypted && this.serverPublicKey && this.keypair) {
|
|
281
|
+
exportedData.serverSigPk = this.serverPublicKey;
|
|
282
|
+
exportedData.secretKey = toBase64Url(this.keypair.secretKey);
|
|
283
|
+
}
|
|
249
284
|
debug('Successfully exported inbox %s', this.emailAddress);
|
|
250
285
|
return exportedData;
|
|
251
286
|
}
|
|
@@ -263,5 +298,98 @@ export class Inbox {
|
|
|
263
298
|
debug('Sync status for inbox %s: %d emails, hash: %s', this.emailAddress, syncStatus.emailCount, syncStatus.emailsHash);
|
|
264
299
|
return syncStatus;
|
|
265
300
|
}
|
|
301
|
+
// ===== Email Cache Management =====
|
|
302
|
+
/**
|
|
303
|
+
* Gets all email IDs currently in the local cache.
|
|
304
|
+
*
|
|
305
|
+
* @returns An array of email IDs.
|
|
306
|
+
*/
|
|
307
|
+
getEmailIds() {
|
|
308
|
+
return Array.from(this.emailCache.keys());
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Gets the local email cache.
|
|
312
|
+
*
|
|
313
|
+
* @returns The email cache map.
|
|
314
|
+
* @internal
|
|
315
|
+
*/
|
|
316
|
+
getEmailCache() {
|
|
317
|
+
return this.emailCache;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Adds an email to the local cache.
|
|
321
|
+
*
|
|
322
|
+
* @param email - The email data to add.
|
|
323
|
+
* @returns `true` if the email was added, `false` if it already existed.
|
|
324
|
+
*/
|
|
325
|
+
addEmail(email) {
|
|
326
|
+
if (this.emailCache.has(email.id)) {
|
|
327
|
+
debug('Email %s already exists in cache for inbox %s', email.id, this.emailAddress);
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
this.emailCache.set(email.id, email);
|
|
331
|
+
debug('Added email %s to cache for inbox %s', email.id, this.emailAddress);
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Removes an email from the local cache.
|
|
336
|
+
*
|
|
337
|
+
* @param emailId - The ID of the email to remove.
|
|
338
|
+
* @returns `true` if the email was removed, `false` if it didn't exist.
|
|
339
|
+
*/
|
|
340
|
+
removeEmail(emailId) {
|
|
341
|
+
const removed = this.emailCache.delete(emailId);
|
|
342
|
+
if (removed) {
|
|
343
|
+
debug('Removed email %s from cache for inbox %s', emailId, this.emailAddress);
|
|
344
|
+
}
|
|
345
|
+
return removed;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Checks if an email exists in the local cache.
|
|
349
|
+
*
|
|
350
|
+
* @param emailId - The ID of the email to check.
|
|
351
|
+
* @returns `true` if the email exists, `false` otherwise.
|
|
352
|
+
*/
|
|
353
|
+
hasEmail(emailId) {
|
|
354
|
+
return this.emailCache.has(emailId);
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Computes the hash of the local email cache.
|
|
358
|
+
*
|
|
359
|
+
* This hash can be compared with the server's hash to detect changes.
|
|
360
|
+
* Uses the algorithm: BASE64URL(SHA256(SORT(emailIds).join(",")))
|
|
361
|
+
*
|
|
362
|
+
* @returns The computed hash of local email IDs.
|
|
363
|
+
*/
|
|
364
|
+
computeLocalHash() {
|
|
365
|
+
const hash = computeEmailsHash(this.getEmailIds());
|
|
366
|
+
debug('Computed local hash for inbox %s: %s', this.emailAddress, hash);
|
|
367
|
+
return hash;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Clears all emails from the local cache.
|
|
371
|
+
*/
|
|
372
|
+
clearEmailCache() {
|
|
373
|
+
this.emailCache.clear();
|
|
374
|
+
debug('Cleared email cache for inbox %s', this.emailAddress);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Gets the keypair for this inbox.
|
|
378
|
+
*
|
|
379
|
+
* @returns The keypair, or null for plain inboxes.
|
|
380
|
+
* @internal
|
|
381
|
+
*/
|
|
382
|
+
getKeypair() {
|
|
383
|
+
return this.keypair;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Gets the API client for this inbox.
|
|
387
|
+
*
|
|
388
|
+
* @returns The API client.
|
|
389
|
+
* @internal
|
|
390
|
+
*/
|
|
391
|
+
getApiClient() {
|
|
392
|
+
return this.apiClient;
|
|
393
|
+
}
|
|
266
394
|
}
|
|
267
395
|
//# sourceMappingURL=inbox.js.map
|