@vaultsandbox/client 0.5.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +612 -0
  3. package/dist/client.d.ts +231 -0
  4. package/dist/client.js +432 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/crypto/constants.d.ts +13 -0
  7. package/dist/crypto/constants.js +14 -0
  8. package/dist/crypto/constants.js.map +1 -0
  9. package/dist/crypto/decrypt.d.ts +41 -0
  10. package/dist/crypto/decrypt.js +112 -0
  11. package/dist/crypto/decrypt.js.map +1 -0
  12. package/dist/crypto/keypair.d.ts +39 -0
  13. package/dist/crypto/keypair.js +109 -0
  14. package/dist/crypto/keypair.js.map +1 -0
  15. package/dist/crypto/signature.d.ts +28 -0
  16. package/dist/crypto/signature.js +89 -0
  17. package/dist/crypto/signature.js.map +1 -0
  18. package/dist/crypto/utils.d.ts +28 -0
  19. package/dist/crypto/utils.js +60 -0
  20. package/dist/crypto/utils.js.map +1 -0
  21. package/dist/email.d.ts +63 -0
  22. package/dist/email.js +186 -0
  23. package/dist/email.js.map +1 -0
  24. package/dist/http/api-client.d.ts +145 -0
  25. package/dist/http/api-client.js +242 -0
  26. package/dist/http/api-client.js.map +1 -0
  27. package/dist/inbox.d.ts +120 -0
  28. package/dist/inbox.js +243 -0
  29. package/dist/inbox.js.map +1 -0
  30. package/dist/index.d.ts +14 -0
  31. package/dist/index.js +17 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/strategies/delivery-strategy.d.ts +29 -0
  34. package/dist/strategies/delivery-strategy.js +2 -0
  35. package/dist/strategies/delivery-strategy.js.map +1 -0
  36. package/dist/strategies/polling-strategy.d.ts +36 -0
  37. package/dist/strategies/polling-strategy.js +146 -0
  38. package/dist/strategies/polling-strategy.js.map +1 -0
  39. package/dist/strategies/sse-strategy.d.ts +49 -0
  40. package/dist/strategies/sse-strategy.js +266 -0
  41. package/dist/strategies/sse-strategy.js.map +1 -0
  42. package/dist/types/index.d.ts +434 -0
  43. package/dist/types/index.js +127 -0
  44. package/dist/types/index.js.map +1 -0
  45. package/dist/utils/email-utils.d.ts +19 -0
  46. package/dist/utils/email-utils.js +92 -0
  47. package/dist/utils/email-utils.js.map +1 -0
  48. package/dist/utils/sleep.d.ts +6 -0
  49. package/dist/utils/sleep.js +9 -0
  50. package/dist/utils/sleep.js.map +1 -0
  51. package/package.json +85 -0
@@ -0,0 +1,434 @@
1
+ /**
2
+ * VaultSandbox Client SDK - Type Definitions
3
+ */
4
+ /**
5
+ * Configuration for the VaultSandboxClient.
6
+ */
7
+ export interface ClientConfig {
8
+ /** The URL of the VaultSandbox Gateway server. */
9
+ url: string;
10
+ /** Your API key for authentication. */
11
+ apiKey: string;
12
+ /**
13
+ * The email delivery strategy to use.
14
+ * - `sse`: Use Server-Sent Events for real-time updates.
15
+ * - `polling`: Use traditional polling.
16
+ * - `auto`: Use SSE if available, otherwise fall back to polling (default).
17
+ */
18
+ strategy?: 'sse' | 'polling' | 'auto';
19
+ /** The base interval for polling in milliseconds (default: 2000). */
20
+ pollingInterval?: number;
21
+ /** The maximum number of retries for failed HTTP requests (default: 3). */
22
+ maxRetries?: number;
23
+ /** The initial delay in milliseconds between retries (default: 1000). */
24
+ retryDelay?: number;
25
+ /** An array of HTTP status codes that should trigger a retry. */
26
+ retryOn?: number[];
27
+ /** The initial interval in milliseconds for SSE reconnection attempts (default: 5000). */
28
+ sseReconnectInterval?: number;
29
+ /** The maximum number of SSE reconnection attempts (default: 10). */
30
+ sseMaxReconnectAttempts?: number;
31
+ }
32
+ /**
33
+ * Options for creating a new inbox.
34
+ */
35
+ export interface CreateInboxOptions {
36
+ /** The time-to-live for the inbox in seconds. */
37
+ ttl?: number;
38
+ /** A specific email address to request for the inbox. */
39
+ emailAddress?: string;
40
+ }
41
+ /**
42
+ * Exported inbox data structure for sharing or backup purposes.
43
+ * Contains all necessary information to import and access an inbox.
44
+ */
45
+ export interface ExportedInboxData {
46
+ /** The email address for this inbox */
47
+ emailAddress: string;
48
+ /** ISO timestamp when the inbox expires */
49
+ expiresAt: string;
50
+ /** Unique hash identifier for the inbox */
51
+ inboxHash: string;
52
+ /** Server's public signing key */
53
+ serverSigPk: string;
54
+ /** Base64-encoded public key */
55
+ publicKeyB64: string;
56
+ /** Base64-encoded secret key for decryption */
57
+ secretKeyB64: string;
58
+ /** ISO timestamp when the inbox was exported */
59
+ exportedAt: string;
60
+ }
61
+ /**
62
+ * Data returned by the server when an inbox is created.
63
+ * Matches the CreateInboxResponseDto from the API.
64
+ * @internal
65
+ */
66
+ export interface InboxData {
67
+ /** The email address assigned to the inbox. */
68
+ emailAddress: string;
69
+ /** ISO 8601 timestamp when the inbox will expire. */
70
+ expiresAt: string;
71
+ /** Base64URL-encoded SHA-256 hash of the client KEM public key, used for SSE subscriptions and API references. */
72
+ inboxHash: string;
73
+ /** Base64URL-encoded server signing public key for verifying server signatures. */
74
+ serverSigPk: string;
75
+ }
76
+ /**
77
+ * The synchronization status of an inbox.
78
+ */
79
+ export interface SyncStatus {
80
+ /** The number of emails in the inbox. */
81
+ emailCount: number;
82
+ /** A hash of the email list, used for efficient change detection. */
83
+ emailsHash: string;
84
+ }
85
+ /**
86
+ * Options for waiting for an email.
87
+ */
88
+ export interface WaitOptions {
89
+ /** The maximum time to wait in milliseconds (default: 30000). */
90
+ timeout?: number;
91
+ /** The interval for polling in milliseconds (default: 2000). */
92
+ pollInterval?: number;
93
+ /** A string or regular expression to match against the email subject. */
94
+ subject?: string | RegExp;
95
+ /** A string or regular expression to match against the sender's email address. */
96
+ from?: string | RegExp;
97
+ /** A custom predicate function to filter emails. */
98
+ predicate?: (email: IEmail) => boolean;
99
+ }
100
+ /**
101
+ * Options for waiting for a specific number of emails.
102
+ */
103
+ export interface WaitForCountOptions {
104
+ /** The maximum time to wait in milliseconds (default: 30000). */
105
+ timeout?: number;
106
+ }
107
+ /**
108
+ * Raw email data returned from the API.
109
+ * @internal
110
+ */
111
+ export interface EmailData {
112
+ id: string;
113
+ inboxId: string;
114
+ receivedAt: string;
115
+ isRead: boolean;
116
+ encryptedMetadata: EncryptedData;
117
+ encryptedParsed?: EncryptedData;
118
+ }
119
+ /**
120
+ * The structure of encrypted data returned from the server.
121
+ * @internal
122
+ */
123
+ export interface EncryptedData {
124
+ v: number;
125
+ ct_kem: string;
126
+ nonce: string;
127
+ aad: string;
128
+ ciphertext: string;
129
+ sig: string;
130
+ server_sig_pk: string;
131
+ algs: {
132
+ kem: string;
133
+ sig: string;
134
+ aead: string;
135
+ kdf: string;
136
+ };
137
+ }
138
+ /**
139
+ * Decrypted email metadata.
140
+ * @internal
141
+ */
142
+ export interface DecryptedMetadata {
143
+ from: string;
144
+ to: string[];
145
+ subject: string;
146
+ receivedAt?: string;
147
+ }
148
+ /**
149
+ * Decrypted and parsed email content.
150
+ * @internal
151
+ */
152
+ export interface DecryptedParsed {
153
+ text: string | null;
154
+ html: string | null;
155
+ headers: Record<string, unknown>;
156
+ attachments: AttachmentData[];
157
+ links?: string[];
158
+ authResults?: AuthResultsData;
159
+ }
160
+ /**
161
+ * Represents an email attachment.
162
+ */
163
+ export interface AttachmentData {
164
+ /** The filename of the attachment. */
165
+ filename: string;
166
+ /** The content type of the attachment. */
167
+ contentType: string;
168
+ /** The size of the attachment in bytes. */
169
+ size: number;
170
+ /** Optional content ID for inline attachments referenced in HTML. */
171
+ contentId?: string;
172
+ /** Content disposition header value (e.g., 'attachment', 'inline'). */
173
+ contentDisposition?: string;
174
+ /** Optional checksum for verifying attachment integrity. */
175
+ checksum?: string;
176
+ /** The content of the attachment as a byte array. */
177
+ content?: Uint8Array;
178
+ }
179
+ /**
180
+ * Represents the raw, decrypted source of an email.
181
+ */
182
+ export interface RawEmail {
183
+ /** The ID of the email. */
184
+ id: string;
185
+ /** The raw email content. */
186
+ raw: string;
187
+ }
188
+ /**
189
+ * @internal
190
+ */
191
+ export interface RawEmailData {
192
+ id: string;
193
+ encryptedRaw: EncryptedData;
194
+ }
195
+ /**
196
+ * The result of an SPF (Sender Policy Framework) validation check.
197
+ */
198
+ export interface SPFResult {
199
+ status: 'pass' | 'fail' | 'softfail' | 'neutral' | 'none' | 'temperror' | 'permerror';
200
+ domain?: string;
201
+ ip?: string;
202
+ info?: string;
203
+ }
204
+ /**
205
+ * The result of a DKIM (DomainKeys Identified Mail) validation check.
206
+ */
207
+ export interface DKIMResult {
208
+ status: 'pass' | 'fail' | 'none';
209
+ domain?: string;
210
+ selector?: string;
211
+ info?: string;
212
+ }
213
+ /**
214
+ * The result of a DMARC (Domain-based Message Authentication, Reporting, and Conformance) validation check.
215
+ */
216
+ export interface DMARCResult {
217
+ status: 'pass' | 'fail' | 'none';
218
+ policy?: 'none' | 'quarantine' | 'reject';
219
+ aligned?: boolean;
220
+ domain?: string;
221
+ info?: string;
222
+ }
223
+ /**
224
+ * The result of a reverse DNS validation check.
225
+ */
226
+ export interface ReverseDNSResult {
227
+ status: 'pass' | 'fail' | 'none';
228
+ ip?: string;
229
+ hostname?: string;
230
+ info?: string;
231
+ }
232
+ /**
233
+ * The raw data for email authentication results.
234
+ */
235
+ export interface AuthResultsData {
236
+ spf?: SPFResult;
237
+ dkim?: DKIMResult[];
238
+ dmarc?: DMARCResult;
239
+ reverseDns?: ReverseDNSResult;
240
+ }
241
+ /**
242
+ * A summary of email authentication validation.
243
+ */
244
+ export interface AuthValidation {
245
+ /** A boolean indicating whether all checks passed. */
246
+ passed: boolean;
247
+ /** A boolean indicating whether the SPF check passed. */
248
+ spfPassed: boolean;
249
+ /** A boolean indicating whether the DKIM check passed. */
250
+ dkimPassed: boolean;
251
+ /** A boolean indicating whether the DMARC check passed. */
252
+ dmarcPassed: boolean;
253
+ /** A boolean indicating whether the reverse DNS check passed. */
254
+ reverseDnsPassed: boolean;
255
+ /** An array of strings describing any failures. */
256
+ failures: string[];
257
+ }
258
+ /**
259
+ * Interface for the Email class.
260
+ */
261
+ export interface IEmail {
262
+ readonly id: string;
263
+ readonly from: string;
264
+ readonly to: string[];
265
+ readonly subject: string;
266
+ readonly receivedAt: Date;
267
+ readonly isRead: boolean;
268
+ readonly text: string | null;
269
+ readonly html: string | null;
270
+ readonly attachments: AttachmentData[];
271
+ readonly links: string[];
272
+ readonly headers: Record<string, unknown>;
273
+ readonly authResults: AuthResults;
274
+ readonly metadata: Record<string, unknown>;
275
+ markAsRead(): Promise<void>;
276
+ delete(): Promise<void>;
277
+ getRaw(): Promise<RawEmail>;
278
+ }
279
+ /**
280
+ * Interface for the AuthResults class.
281
+ */
282
+ export interface AuthResults extends AuthResultsData {
283
+ validate(): AuthValidation;
284
+ }
285
+ /**
286
+ * Information about the VaultSandbox server.
287
+ */
288
+ export interface ServerInfo {
289
+ /** Base64URL-encoded server signing public key for ML-DSA-65. */
290
+ serverSigPk: string;
291
+ /** Cryptographic algorithms supported by the server. */
292
+ algs: {
293
+ /** Key encapsulation mechanism algorithm (e.g., 'ML-KEM-768'). */
294
+ kem: string;
295
+ /** Digital signature algorithm (e.g., 'ML-DSA-65'). */
296
+ sig: string;
297
+ /** Authenticated encryption algorithm (e.g., 'AES-256-GCM'). */
298
+ aead: string;
299
+ /** Key derivation function (e.g., 'HKDF-SHA-512'). */
300
+ kdf: string;
301
+ };
302
+ /** Context string for the encryption scheme. */
303
+ context: string;
304
+ /** Maximum time-to-live for inboxes in seconds. */
305
+ maxTtl: number;
306
+ /** Default time-to-live for inboxes in seconds. */
307
+ defaultTtl: number;
308
+ /** Whether the server SSE console is enabled. */
309
+ sseConsole: boolean;
310
+ /** List of domains allowed for inbox creation. */
311
+ allowedDomains: string[];
312
+ }
313
+ /**
314
+ * Represents a subscription to an event source, such as new emails.
315
+ */
316
+ export interface Subscription {
317
+ /** Unsubscribes from the event source and cleans up resources. */
318
+ unsubscribe(): void;
319
+ }
320
+ /**
321
+ * @internal
322
+ */
323
+ export interface SSEConfig {
324
+ url: string;
325
+ apiKey: string;
326
+ reconnectInterval?: number;
327
+ maxReconnectAttempts?: number;
328
+ backoffMultiplier?: number;
329
+ }
330
+ /**
331
+ * @internal
332
+ */
333
+ export interface SSEEvent {
334
+ inboxHash: string;
335
+ emailId: string;
336
+ emailData: EmailData;
337
+ }
338
+ /**
339
+ * @internal
340
+ */
341
+ export interface SSEMessageData {
342
+ inboxId: string;
343
+ emailId: string;
344
+ encryptedMetadata: EncryptedData;
345
+ }
346
+ /**
347
+ * A quantum-safe keypair used for encryption and decryption.
348
+ * @internal
349
+ */
350
+ export interface Keypair {
351
+ publicKey: Uint8Array;
352
+ secretKey: Uint8Array;
353
+ publicKeyB64: string;
354
+ }
355
+ /**
356
+ * @internal
357
+ */
358
+ export interface DecryptionResult {
359
+ plaintext: Uint8Array;
360
+ verified: boolean;
361
+ }
362
+ /**
363
+ * Base class for all errors thrown by the VaultSandbox client.
364
+ */
365
+ export declare class VaultSandboxError extends Error {
366
+ constructor(message: string);
367
+ }
368
+ /**
369
+ * An error thrown when the API returns a non-successful status code.
370
+ */
371
+ export declare class ApiError extends VaultSandboxError {
372
+ statusCode: number;
373
+ constructor(statusCode: number, message: string);
374
+ }
375
+ /**
376
+ * An error thrown when a network error occurs.
377
+ */
378
+ export declare class NetworkError extends VaultSandboxError {
379
+ constructor(message: string);
380
+ }
381
+ /**
382
+ * An error thrown when an operation times out.
383
+ */
384
+ export declare class TimeoutError extends VaultSandboxError {
385
+ constructor(message: string);
386
+ }
387
+ /**
388
+ * An error thrown when decryption fails.
389
+ */
390
+ export declare class DecryptionError extends VaultSandboxError {
391
+ constructor(message: string);
392
+ }
393
+ /**
394
+ * An error thrown when signature verification fails.
395
+ */
396
+ export declare class SignatureVerificationError extends VaultSandboxError {
397
+ constructor(message: string);
398
+ }
399
+ /**
400
+ * An error thrown when an inbox is not found.
401
+ */
402
+ export declare class InboxNotFoundError extends VaultSandboxError {
403
+ constructor(message: string);
404
+ }
405
+ /**
406
+ * An error thrown when an email is not found.
407
+ */
408
+ export declare class EmailNotFoundError extends VaultSandboxError {
409
+ constructor(message: string);
410
+ }
411
+ /**
412
+ * An error thrown when an SSE (Server-Sent Events) error occurs.
413
+ */
414
+ export declare class SSEError extends VaultSandboxError {
415
+ constructor(message: string);
416
+ }
417
+ /**
418
+ * An error thrown when trying to import an inbox that already exists.
419
+ */
420
+ export declare class InboxAlreadyExistsError extends VaultSandboxError {
421
+ constructor(message: string);
422
+ }
423
+ /**
424
+ * An error thrown when imported inbox data fails validation.
425
+ */
426
+ export declare class InvalidImportDataError extends VaultSandboxError {
427
+ constructor(message: string);
428
+ }
429
+ /**
430
+ * An error thrown when a delivery strategy is not set or is invalid.
431
+ */
432
+ export declare class StrategyError extends VaultSandboxError {
433
+ constructor(message: string);
434
+ }
@@ -0,0 +1,127 @@
1
+ /**
2
+ * VaultSandbox Client SDK - Type Definitions
3
+ */
4
+ // ===== Errors =====
5
+ /**
6
+ * Base class for all errors thrown by the VaultSandbox client.
7
+ */
8
+ export class VaultSandboxError extends Error {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = 'VaultSandboxError';
12
+ Object.setPrototypeOf(this, VaultSandboxError.prototype);
13
+ }
14
+ }
15
+ /**
16
+ * An error thrown when the API returns a non-successful status code.
17
+ */
18
+ export class ApiError extends VaultSandboxError {
19
+ statusCode;
20
+ constructor(statusCode, message) {
21
+ super(message);
22
+ this.statusCode = statusCode;
23
+ this.name = 'ApiError';
24
+ Object.setPrototypeOf(this, ApiError.prototype);
25
+ }
26
+ }
27
+ /**
28
+ * An error thrown when a network error occurs.
29
+ */
30
+ export class NetworkError extends VaultSandboxError {
31
+ constructor(message) {
32
+ super(message);
33
+ this.name = 'NetworkError';
34
+ Object.setPrototypeOf(this, NetworkError.prototype);
35
+ }
36
+ }
37
+ /**
38
+ * An error thrown when an operation times out.
39
+ */
40
+ export class TimeoutError extends VaultSandboxError {
41
+ constructor(message) {
42
+ super(message);
43
+ this.name = 'TimeoutError';
44
+ Object.setPrototypeOf(this, TimeoutError.prototype);
45
+ }
46
+ }
47
+ /**
48
+ * An error thrown when decryption fails.
49
+ */
50
+ export class DecryptionError extends VaultSandboxError {
51
+ constructor(message) {
52
+ super(message);
53
+ this.name = 'DecryptionError';
54
+ Object.setPrototypeOf(this, DecryptionError.prototype);
55
+ }
56
+ }
57
+ /**
58
+ * An error thrown when signature verification fails.
59
+ */
60
+ export class SignatureVerificationError extends VaultSandboxError {
61
+ constructor(message) {
62
+ super(message);
63
+ this.name = 'SignatureVerificationError';
64
+ Object.setPrototypeOf(this, SignatureVerificationError.prototype);
65
+ }
66
+ }
67
+ /**
68
+ * An error thrown when an inbox is not found.
69
+ */
70
+ export class InboxNotFoundError extends VaultSandboxError {
71
+ constructor(message) {
72
+ super(message);
73
+ this.name = 'InboxNotFoundError';
74
+ Object.setPrototypeOf(this, InboxNotFoundError.prototype);
75
+ }
76
+ }
77
+ /**
78
+ * An error thrown when an email is not found.
79
+ */
80
+ export class EmailNotFoundError extends VaultSandboxError {
81
+ constructor(message) {
82
+ super(message);
83
+ this.name = 'EmailNotFoundError';
84
+ Object.setPrototypeOf(this, EmailNotFoundError.prototype);
85
+ }
86
+ }
87
+ /**
88
+ * An error thrown when an SSE (Server-Sent Events) error occurs.
89
+ */
90
+ export class SSEError extends VaultSandboxError {
91
+ constructor(message) {
92
+ super(message);
93
+ this.name = 'SSEError';
94
+ Object.setPrototypeOf(this, SSEError.prototype);
95
+ }
96
+ }
97
+ /**
98
+ * An error thrown when trying to import an inbox that already exists.
99
+ */
100
+ export class InboxAlreadyExistsError extends VaultSandboxError {
101
+ constructor(message) {
102
+ super(message);
103
+ this.name = 'InboxAlreadyExistsError';
104
+ Object.setPrototypeOf(this, InboxAlreadyExistsError.prototype);
105
+ }
106
+ }
107
+ /**
108
+ * An error thrown when imported inbox data fails validation.
109
+ */
110
+ export class InvalidImportDataError extends VaultSandboxError {
111
+ constructor(message) {
112
+ super(message);
113
+ this.name = 'InvalidImportDataError';
114
+ Object.setPrototypeOf(this, InvalidImportDataError.prototype);
115
+ }
116
+ }
117
+ /**
118
+ * An error thrown when a delivery strategy is not set or is invalid.
119
+ */
120
+ export class StrategyError extends VaultSandboxError {
121
+ constructor(message) {
122
+ super(message);
123
+ this.name = 'StrategyError';
124
+ Object.setPrototypeOf(this, StrategyError.prototype);
125
+ }
126
+ }
127
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AA8ZH,qBAAqB;AAErB;;GAEG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,QAAS,SAAQ,iBAAiB;IAEpC;IADT,YACS,UAAkB,EACzB,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAHR,eAAU,GAAV,UAAU,CAAQ;QAIzB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,iBAAiB;IACjD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,iBAAiB;IACjD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,iBAAiB;IACpD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,0BAA2B,SAAQ,iBAAiB;IAC/D,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;QACzC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,0BAA0B,CAAC,SAAS,CAAC,CAAC;IACpE,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,kBAAmB,SAAQ,iBAAiB;IACvD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC5D,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,kBAAmB,SAAQ,iBAAiB;IACvD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC5D,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,QAAS,SAAQ,iBAAiB;IAC7C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,uBAAwB,SAAQ,iBAAiB;IAC5D,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;QACtC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,uBAAuB,CAAC,SAAS,CAAC,CAAC;IACjE,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,sBAAuB,SAAQ,iBAAiB;IAC3D,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,iBAAiB;IAClD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACvD,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Shared email utilities for decryption and filtering
3
+ */
4
+ import type { Keypair, EmailData, IEmail, WaitOptions } from '../types/index.js';
5
+ import type { ApiClient } from '../http/api-client.js';
6
+ /**
7
+ * Decrypts an EmailData object into an Email instance.
8
+ * If only metadata is present, fetch the full email (including parsed content) first.
9
+ * IMPORTANT: Signature verification happens BEFORE decryption for security
10
+ */
11
+ export declare function decryptEmailData(emailData: EmailData, keypair: Keypair, emailAddress: string, apiClient: ApiClient): Promise<IEmail>;
12
+ /**
13
+ * Finds the first email matching the specified criteria
14
+ */
15
+ export declare function findMatchingEmail(emails: IEmail[], options: WaitOptions): IEmail | null;
16
+ /**
17
+ * Check if email matches the specified filters
18
+ */
19
+ export declare function matchesFilters(email: IEmail, options: WaitOptions): boolean;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Shared email utilities for decryption and filtering
3
+ */
4
+ import { Email } from '../email.js';
5
+ import { decryptMetadata, decryptParsed } from '../crypto/decrypt.js';
6
+ import { verifySignature } from '../crypto/signature.js';
7
+ import { fromBase64 } from '../crypto/utils.js';
8
+ /**
9
+ * Decrypts an EmailData object into an Email instance.
10
+ * If only metadata is present, fetch the full email (including parsed content) first.
11
+ * IMPORTANT: Signature verification happens BEFORE decryption for security
12
+ */
13
+ export async function decryptEmailData(emailData, keypair, emailAddress, apiClient) {
14
+ const fullEmailData = emailData.encryptedParsed ? emailData : await apiClient.getEmail(emailAddress, emailData.id);
15
+ // Verify signature FIRST (before decryption) - signature includes server public key
16
+ verifySignature(fullEmailData.encryptedMetadata);
17
+ // Decrypt metadata
18
+ const metadata = await decryptMetadata(fullEmailData.encryptedMetadata, keypair);
19
+ // Decrypt parsed content if available
20
+ let parsed = null;
21
+ if (fullEmailData.encryptedParsed) {
22
+ // Verify signature for parsed content too
23
+ verifySignature(fullEmailData.encryptedParsed);
24
+ parsed = await decryptParsed(fullEmailData.encryptedParsed, keypair);
25
+ // Transform attachment content from base64 strings to Uint8Array
26
+ // The server returns attachment content as base64-encoded strings, but our type expects Uint8Array
27
+ if (parsed?.attachments) {
28
+ parsed.attachments = parsed.attachments.map((att) => {
29
+ // Check if content exists and is a string (base64 encoded)
30
+ if (att.content && typeof att.content === 'string') {
31
+ return {
32
+ ...att,
33
+ content: fromBase64(att.content),
34
+ };
35
+ }
36
+ // Content is already Uint8Array or undefined
37
+ return att;
38
+ });
39
+ }
40
+ }
41
+ return new Email(fullEmailData, metadata, parsed, emailAddress, apiClient, keypair);
42
+ }
43
+ /**
44
+ * Finds the first email matching the specified criteria
45
+ */
46
+ export function findMatchingEmail(emails, options) {
47
+ for (const email of emails) {
48
+ if (matchesFilters(email, options)) {
49
+ return email;
50
+ }
51
+ }
52
+ return null;
53
+ }
54
+ /**
55
+ * Check if email matches the specified filters
56
+ */
57
+ export function matchesFilters(email, options) {
58
+ // Check subject filter
59
+ if (options.subject) {
60
+ if (typeof options.subject === 'string') {
61
+ if (!email.subject.includes(options.subject)) {
62
+ return false;
63
+ }
64
+ }
65
+ else if (options.subject instanceof RegExp) {
66
+ if (!options.subject.test(email.subject)) {
67
+ return false;
68
+ }
69
+ }
70
+ }
71
+ // Check from filter
72
+ if (options.from) {
73
+ if (typeof options.from === 'string') {
74
+ if (!email.from.includes(options.from)) {
75
+ return false;
76
+ }
77
+ }
78
+ else if (options.from instanceof RegExp) {
79
+ if (!options.from.test(email.from)) {
80
+ return false;
81
+ }
82
+ }
83
+ }
84
+ // Check custom predicate
85
+ if (options.predicate) {
86
+ if (!options.predicate(email)) {
87
+ return false;
88
+ }
89
+ }
90
+ return true;
91
+ }
92
+ //# sourceMappingURL=email-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-utils.js","sourceRoot":"","sources":["../../src/utils/email-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Pauses execution for a specified number of milliseconds.
3
+ * @param ms - The number of milliseconds to sleep.
4
+ * @returns A promise that resolves after the specified delay.
5
+ */
6
+ export declare function sleep(ms: number): Promise<void>;