@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.
- package/LICENSE +21 -0
- package/README.md +612 -0
- package/dist/client.d.ts +231 -0
- package/dist/client.js +432 -0
- package/dist/client.js.map +1 -0
- package/dist/crypto/constants.d.ts +13 -0
- package/dist/crypto/constants.js +14 -0
- package/dist/crypto/constants.js.map +1 -0
- package/dist/crypto/decrypt.d.ts +41 -0
- package/dist/crypto/decrypt.js +112 -0
- package/dist/crypto/decrypt.js.map +1 -0
- package/dist/crypto/keypair.d.ts +39 -0
- package/dist/crypto/keypair.js +109 -0
- package/dist/crypto/keypair.js.map +1 -0
- package/dist/crypto/signature.d.ts +28 -0
- package/dist/crypto/signature.js +89 -0
- package/dist/crypto/signature.js.map +1 -0
- package/dist/crypto/utils.d.ts +28 -0
- package/dist/crypto/utils.js +60 -0
- package/dist/crypto/utils.js.map +1 -0
- package/dist/email.d.ts +63 -0
- package/dist/email.js +186 -0
- package/dist/email.js.map +1 -0
- package/dist/http/api-client.d.ts +145 -0
- package/dist/http/api-client.js +242 -0
- package/dist/http/api-client.js.map +1 -0
- package/dist/inbox.d.ts +120 -0
- package/dist/inbox.js +243 -0
- package/dist/inbox.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/strategies/delivery-strategy.d.ts +29 -0
- package/dist/strategies/delivery-strategy.js +2 -0
- package/dist/strategies/delivery-strategy.js.map +1 -0
- package/dist/strategies/polling-strategy.d.ts +36 -0
- package/dist/strategies/polling-strategy.js +146 -0
- package/dist/strategies/polling-strategy.js.map +1 -0
- package/dist/strategies/sse-strategy.d.ts +49 -0
- package/dist/strategies/sse-strategy.js +266 -0
- package/dist/strategies/sse-strategy.js.map +1 -0
- package/dist/types/index.d.ts +434 -0
- package/dist/types/index.js +127 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/email-utils.d.ts +19 -0
- package/dist/utils/email-utils.js +92 -0
- package/dist/utils/email-utils.js.map +1 -0
- package/dist/utils/sleep.d.ts +6 -0
- package/dist/utils/sleep.js +9 -0
- package/dist/utils/sleep.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ApiClient } from '../http/api-client.js';
|
|
2
|
+
import type { Keypair, IEmail, WaitOptions, Subscription, SSEConfig } from '../types/index.js';
|
|
3
|
+
import type { DeliveryStrategy } from './delivery-strategy.js';
|
|
4
|
+
export declare class SSEStrategy implements DeliveryStrategy {
|
|
5
|
+
private apiClient;
|
|
6
|
+
private url;
|
|
7
|
+
private apiKey;
|
|
8
|
+
private reconnectInterval;
|
|
9
|
+
private maxReconnectAttempts;
|
|
10
|
+
private backoffMultiplier;
|
|
11
|
+
private eventSource;
|
|
12
|
+
private subscriptions;
|
|
13
|
+
private reconnectAttempts;
|
|
14
|
+
private reconnectTimer;
|
|
15
|
+
private isClosing;
|
|
16
|
+
constructor(apiClient: ApiClient, config: SSEConfig);
|
|
17
|
+
/**
|
|
18
|
+
* Wait for an email matching the specified criteria using SSE
|
|
19
|
+
*/
|
|
20
|
+
waitForEmail(emailAddress: string, inboxHash: string, keypair: Keypair, options?: WaitOptions): Promise<IEmail>;
|
|
21
|
+
/**
|
|
22
|
+
* Subscribe to new email notifications for a specific inbox
|
|
23
|
+
*/
|
|
24
|
+
subscribe(emailAddress: string, inboxHash: string, keypair: Keypair, callback: (email: IEmail) => void | Promise<void>): Subscription;
|
|
25
|
+
/**
|
|
26
|
+
* Connect to SSE endpoint
|
|
27
|
+
*/
|
|
28
|
+
private connect;
|
|
29
|
+
/**
|
|
30
|
+
* Handle incoming SSE message
|
|
31
|
+
*/
|
|
32
|
+
private handleMessage;
|
|
33
|
+
/**
|
|
34
|
+
* Handle connection error and attempt reconnection
|
|
35
|
+
*/
|
|
36
|
+
private handleConnectionError;
|
|
37
|
+
/**
|
|
38
|
+
* Reconnect with updated inbox list
|
|
39
|
+
*/
|
|
40
|
+
private reconnect;
|
|
41
|
+
/**
|
|
42
|
+
* Disconnect from SSE endpoint
|
|
43
|
+
*/
|
|
44
|
+
private disconnect;
|
|
45
|
+
/**
|
|
46
|
+
* Close strategy and cleanup resources
|
|
47
|
+
*/
|
|
48
|
+
close(): void;
|
|
49
|
+
}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import createDebug from 'debug';
|
|
2
|
+
import { EventSource } from 'eventsource';
|
|
3
|
+
import { TimeoutError, SSEError } from '../types/index.js';
|
|
4
|
+
import { decryptEmailData, matchesFilters } from '../utils/email-utils.js';
|
|
5
|
+
const debug = createDebug('vaultsandbox:sse-strategy');
|
|
6
|
+
export class SSEStrategy {
|
|
7
|
+
apiClient;
|
|
8
|
+
url;
|
|
9
|
+
apiKey;
|
|
10
|
+
reconnectInterval;
|
|
11
|
+
maxReconnectAttempts;
|
|
12
|
+
backoffMultiplier;
|
|
13
|
+
eventSource = null;
|
|
14
|
+
subscriptions = new Map();
|
|
15
|
+
reconnectAttempts = 0;
|
|
16
|
+
reconnectTimer = null;
|
|
17
|
+
isClosing = false;
|
|
18
|
+
constructor(apiClient, config) {
|
|
19
|
+
this.apiClient = apiClient;
|
|
20
|
+
this.url = config.url;
|
|
21
|
+
this.apiKey = config.apiKey;
|
|
22
|
+
this.reconnectInterval = config.reconnectInterval ?? 5000;
|
|
23
|
+
this.maxReconnectAttempts = config.maxReconnectAttempts ?? 10;
|
|
24
|
+
this.backoffMultiplier = config.backoffMultiplier ?? 2;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Wait for an email matching the specified criteria using SSE
|
|
28
|
+
*/
|
|
29
|
+
async waitForEmail(emailAddress, inboxHash, keypair, options = {}) {
|
|
30
|
+
const timeout = options.timeout ?? 30000;
|
|
31
|
+
const startTime = Date.now();
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
let resolved = false;
|
|
34
|
+
const timeoutTimer = setTimeout(() => {
|
|
35
|
+
if (!resolved) {
|
|
36
|
+
subscription.unsubscribe();
|
|
37
|
+
reject(new TimeoutError('No matching email received within timeout'));
|
|
38
|
+
}
|
|
39
|
+
}, timeout);
|
|
40
|
+
const subscription = this.subscribe(emailAddress, inboxHash, keypair, async (email) => {
|
|
41
|
+
if (resolved)
|
|
42
|
+
return;
|
|
43
|
+
// Check if email matches filters
|
|
44
|
+
if (matchesFilters(email, options)) {
|
|
45
|
+
resolved = true;
|
|
46
|
+
clearTimeout(timeoutTimer);
|
|
47
|
+
subscription.unsubscribe();
|
|
48
|
+
resolve(email);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
// If we're past the timeout already, reject immediately
|
|
52
|
+
if (Date.now() - startTime >= timeout) {
|
|
53
|
+
resolved = true;
|
|
54
|
+
clearTimeout(timeoutTimer);
|
|
55
|
+
subscription.unsubscribe();
|
|
56
|
+
reject(new TimeoutError('No matching email received within timeout'));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Subscribe to new email notifications for a specific inbox
|
|
62
|
+
*/
|
|
63
|
+
subscribe(emailAddress, inboxHash, keypair, callback) {
|
|
64
|
+
// Get or create subscription entry
|
|
65
|
+
let subscription = this.subscriptions.get(emailAddress);
|
|
66
|
+
if (!subscription) {
|
|
67
|
+
subscription = {
|
|
68
|
+
emailAddress,
|
|
69
|
+
inboxHash,
|
|
70
|
+
keypair,
|
|
71
|
+
callbacks: new Set(),
|
|
72
|
+
};
|
|
73
|
+
this.subscriptions.set(emailAddress, subscription);
|
|
74
|
+
}
|
|
75
|
+
// Add callback
|
|
76
|
+
subscription.callbacks.add(callback);
|
|
77
|
+
// Connect or reconnect with updated inbox list
|
|
78
|
+
if (!this.eventSource || this.eventSource.readyState === 2) {
|
|
79
|
+
// 2 = CLOSED
|
|
80
|
+
this.connect();
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// Reconnect to include the new inbox
|
|
84
|
+
this.reconnect();
|
|
85
|
+
}
|
|
86
|
+
// Return unsubscribe function
|
|
87
|
+
return {
|
|
88
|
+
unsubscribe: () => {
|
|
89
|
+
const sub = this.subscriptions.get(emailAddress);
|
|
90
|
+
if (sub) {
|
|
91
|
+
sub.callbacks.delete(callback);
|
|
92
|
+
if (sub.callbacks.size === 0) {
|
|
93
|
+
this.subscriptions.delete(emailAddress);
|
|
94
|
+
if (this.subscriptions.size === 0) {
|
|
95
|
+
this.disconnect();
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// Reconnect with updated inbox list
|
|
99
|
+
this.reconnect();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Connect to SSE endpoint
|
|
108
|
+
*/
|
|
109
|
+
connect() {
|
|
110
|
+
if (this.isClosing)
|
|
111
|
+
return;
|
|
112
|
+
if (this.subscriptions.size === 0)
|
|
113
|
+
return;
|
|
114
|
+
// Build inbox hashes list
|
|
115
|
+
const inboxHashes = Array.from(this.subscriptions.values())
|
|
116
|
+
.map((sub) => sub.inboxHash)
|
|
117
|
+
.filter((hash) => hash) // Filter out empty hashes
|
|
118
|
+
.join(',');
|
|
119
|
+
if (!inboxHashes) {
|
|
120
|
+
debug('No inbox hashes available, skipping connect');
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const sseUrl = `${this.url}/api/events?inboxes=${inboxHashes}`;
|
|
124
|
+
debug('Connecting to SSE endpoint: %s', sseUrl);
|
|
125
|
+
debug('Using API key: %s', this.apiKey ? `${this.apiKey.substring(0, 10)}...` : 'MISSING');
|
|
126
|
+
try {
|
|
127
|
+
// Use custom fetch to add authentication headers
|
|
128
|
+
const eventSourceOptions = {
|
|
129
|
+
fetch: (input, init) => {
|
|
130
|
+
debug('Custom fetch called with headers');
|
|
131
|
+
return fetch(input, {
|
|
132
|
+
...init,
|
|
133
|
+
headers: {
|
|
134
|
+
...(init?.headers || {}),
|
|
135
|
+
'X-API-Key': this.apiKey,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
// The EventSource polyfill for Node supports a custom fetch option, but the
|
|
141
|
+
// DOM EventSource typings don't include it; cast through unknown for Node-only usage.
|
|
142
|
+
this.eventSource = new EventSource(sseUrl, eventSourceOptions);
|
|
143
|
+
debug('EventSource created successfully with custom fetch');
|
|
144
|
+
if (this.eventSource) {
|
|
145
|
+
this.eventSource.onopen = () => {
|
|
146
|
+
debug('SSE connection established');
|
|
147
|
+
this.reconnectAttempts = 0; // Reset reconnect counter
|
|
148
|
+
};
|
|
149
|
+
this.eventSource.onmessage = async (event) => {
|
|
150
|
+
try {
|
|
151
|
+
await this.handleMessage(event.data);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
debug('Error handling SSE message: %O', error);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
this.eventSource.onerror = (error) => {
|
|
158
|
+
debug('SSE connection error: %O', error);
|
|
159
|
+
this.handleConnectionError();
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
debug('Failed to create EventSource: %O', error);
|
|
165
|
+
this.handleConnectionError();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Handle incoming SSE message
|
|
170
|
+
*/
|
|
171
|
+
async handleMessage(data) {
|
|
172
|
+
try {
|
|
173
|
+
debug('Received message: %s', data.substring(0, 200));
|
|
174
|
+
const messageData = JSON.parse(data);
|
|
175
|
+
debug('Parsed message data: %s', JSON.stringify(messageData, null, 2).substring(0, 500));
|
|
176
|
+
const { inboxId, emailId, encryptedMetadata } = messageData;
|
|
177
|
+
debug('Looking for subscription with inboxId: %s', inboxId);
|
|
178
|
+
debug('Available subscriptions: %O', Array.from(this.subscriptions.keys()));
|
|
179
|
+
// Find matching subscription by inboxHash (which matches inboxId from server)
|
|
180
|
+
const subscription = Array.from(this.subscriptions.values()).find((sub) => sub.inboxHash === inboxId);
|
|
181
|
+
if (!subscription) {
|
|
182
|
+
debug('No subscription found for inbox ID: %s', inboxId);
|
|
183
|
+
debug('Available inbox hashes: %O', Array.from(this.subscriptions.values()).map((s) => s.inboxHash));
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// Construct EmailData object from SSE message
|
|
187
|
+
const emailData = {
|
|
188
|
+
id: emailId,
|
|
189
|
+
inboxId: inboxId,
|
|
190
|
+
receivedAt: new Date().toISOString(), // SSE doesn't provide this, use current time
|
|
191
|
+
isRead: false,
|
|
192
|
+
encryptedMetadata: encryptedMetadata,
|
|
193
|
+
};
|
|
194
|
+
// Decrypt email
|
|
195
|
+
const email = await decryptEmailData(emailData, subscription.keypair, subscription.emailAddress, this.apiClient);
|
|
196
|
+
// Notify all callbacks for this inbox
|
|
197
|
+
subscription.callbacks.forEach((callback) => {
|
|
198
|
+
try {
|
|
199
|
+
const result = callback(email);
|
|
200
|
+
// Handle case where callback returns a promise
|
|
201
|
+
if (result instanceof Promise) {
|
|
202
|
+
result.catch((error) => {
|
|
203
|
+
debug('Error in async subscription callback: %O', error);
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
debug('Error in subscription callback: %O', error);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
debug('Error processing SSE message: %O', error);
|
|
214
|
+
throw new SSEError(`Failed to process SSE message: ${error}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Handle connection error and attempt reconnection
|
|
219
|
+
*/
|
|
220
|
+
handleConnectionError() {
|
|
221
|
+
if (this.isClosing)
|
|
222
|
+
return;
|
|
223
|
+
this.disconnect();
|
|
224
|
+
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
225
|
+
const backoffDelay = this.reconnectInterval * Math.pow(this.backoffMultiplier, this.reconnectAttempts);
|
|
226
|
+
debug('Reconnecting in %dms (attempt %d/%d)', backoffDelay, this.reconnectAttempts + 1, this.maxReconnectAttempts);
|
|
227
|
+
this.reconnectTimer = setTimeout(() => {
|
|
228
|
+
this.reconnectAttempts++;
|
|
229
|
+
this.connect();
|
|
230
|
+
}, backoffDelay);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
debug('Max reconnection attempts reached');
|
|
234
|
+
throw new SSEError('Failed to establish SSE connection after maximum retry attempts');
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Reconnect with updated inbox list
|
|
239
|
+
*/
|
|
240
|
+
reconnect() {
|
|
241
|
+
this.disconnect();
|
|
242
|
+
this.connect();
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Disconnect from SSE endpoint
|
|
246
|
+
*/
|
|
247
|
+
disconnect() {
|
|
248
|
+
if (this.reconnectTimer) {
|
|
249
|
+
clearTimeout(this.reconnectTimer);
|
|
250
|
+
this.reconnectTimer = null;
|
|
251
|
+
}
|
|
252
|
+
if (this.eventSource) {
|
|
253
|
+
this.eventSource.close();
|
|
254
|
+
this.eventSource = null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Close strategy and cleanup resources
|
|
259
|
+
*/
|
|
260
|
+
close() {
|
|
261
|
+
this.isClosing = true;
|
|
262
|
+
this.disconnect();
|
|
263
|
+
this.subscriptions.clear();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=sse-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse-strategy.js","sourceRoot":"","sources":["../../src/strategies/sse-strategy.ts"],"names":[],"mappings":"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"}
|