@haex-space/vault-sdk 3.0.0 → 3.2.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/dist/{client-dpJHb3FP.d.ts → client-GeColu97.d.mts} +270 -2
- package/dist/{client-BXtzUBWv.d.mts → client-z1jTcuQE.d.ts} +270 -2
- package/dist/index.d.mts +93 -6
- package/dist/index.d.ts +93 -6
- package/dist/index.js +301 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +298 -46
- package/dist/index.mjs.map +1 -1
- package/dist/node.d.mts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/nuxt.js +34 -7
- package/dist/nuxt.js.map +1 -1
- package/dist/nuxt.mjs +34 -7
- package/dist/nuxt.mjs.map +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +294 -44
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +294 -44
- package/dist/react.mjs.map +1 -1
- package/dist/runtime/nuxt.plugin.client.d.mts +2 -2
- package/dist/runtime/nuxt.plugin.client.d.ts +2 -2
- package/dist/runtime/nuxt.plugin.client.js +294 -48
- package/dist/runtime/nuxt.plugin.client.js.map +1 -1
- package/dist/runtime/nuxt.plugin.client.mjs +294 -48
- package/dist/runtime/nuxt.plugin.client.mjs.map +1 -1
- package/dist/svelte.d.mts +2 -2
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js +294 -44
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +294 -44
- package/dist/svelte.mjs.map +1 -1
- package/dist/{types-DmCSegdY.d.mts → types-CDMBvvjl.d.mts} +2 -0
- package/dist/{types-DmCSegdY.d.ts → types-CDMBvvjl.d.ts} +2 -0
- package/dist/vite.js +33 -6
- package/dist/vite.js.map +1 -1
- package/dist/vite.mjs +33 -6
- package/dist/vite.mjs.map +1 -1
- package/dist/vue.d.mts +2 -2
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +294 -44
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +294 -44
- package/dist/vue.mjs.map +1 -1
- package/package.json +2 -1
|
@@ -265,6 +265,40 @@ var SHELL_COMMANDS = {
|
|
|
265
265
|
close: "extension_shell_close"
|
|
266
266
|
};
|
|
267
267
|
|
|
268
|
+
// src/commands/passwords.ts
|
|
269
|
+
var PASSWORD_COMMANDS = {
|
|
270
|
+
/** List items (no secrets) within the extension's tag scope */
|
|
271
|
+
list: "extension_password_list",
|
|
272
|
+
/** Read full item including secrets, by id */
|
|
273
|
+
read: "extension_password_read",
|
|
274
|
+
/** Create item — must include >=1 tag in scope */
|
|
275
|
+
create: "extension_password_create",
|
|
276
|
+
/** Update item — keeps >=1 tag in scope */
|
|
277
|
+
update: "extension_password_update",
|
|
278
|
+
/** Delete item — must be in scope */
|
|
279
|
+
delete: "extension_password_delete"
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
// src/commands/mail.ts
|
|
283
|
+
var MAIL_COMMANDS = {
|
|
284
|
+
/** LIST mailboxes + optional STATUS counts */
|
|
285
|
+
listMailboxes: "extension_mail_list_mailboxes",
|
|
286
|
+
/** Lightweight envelope fetch for list views */
|
|
287
|
+
fetchEnvelopes: "extension_mail_fetch_envelopes",
|
|
288
|
+
/** Full message fetch (envelope + body + attachment metadata) */
|
|
289
|
+
fetchMessage: "extension_mail_fetch_message",
|
|
290
|
+
/** Set or unset IMAP flags on a UID set */
|
|
291
|
+
setFlags: "extension_mail_set_flags",
|
|
292
|
+
/** MOVE messages between mailboxes (COPY+EXPUNGE fallback) */
|
|
293
|
+
moveMessages: "extension_mail_move_messages",
|
|
294
|
+
/** APPEND a base64-encoded RFC822 message into a mailbox */
|
|
295
|
+
appendMessage: "extension_mail_append_message",
|
|
296
|
+
/** SMTP send. Returns the assigned Message-ID. */
|
|
297
|
+
sendMessage: "extension_mail_send_message",
|
|
298
|
+
/** Build RFC822 bytes without sending (for Drafts via APPEND) */
|
|
299
|
+
buildRfc822: "extension_mail_build_rfc822"
|
|
300
|
+
};
|
|
301
|
+
|
|
268
302
|
// src/api/storage.ts
|
|
269
303
|
var StorageAPI = class {
|
|
270
304
|
constructor(client) {
|
|
@@ -288,6 +322,12 @@ var StorageAPI = class {
|
|
|
288
322
|
};
|
|
289
323
|
|
|
290
324
|
// src/api/database.ts
|
|
325
|
+
function quoteIdent(identifier) {
|
|
326
|
+
if (identifier.startsWith('"') && identifier.endsWith('"')) {
|
|
327
|
+
return identifier;
|
|
328
|
+
}
|
|
329
|
+
return `"${identifier.replace(/"/g, '""')}"`;
|
|
330
|
+
}
|
|
291
331
|
var DatabaseAPI = class {
|
|
292
332
|
constructor(client) {
|
|
293
333
|
this.client = client;
|
|
@@ -318,11 +358,11 @@ var DatabaseAPI = class {
|
|
|
318
358
|
});
|
|
319
359
|
}
|
|
320
360
|
async createTable(tableName, columns) {
|
|
321
|
-
const query = `CREATE TABLE IF NOT EXISTS ${tableName} (${columns})`;
|
|
361
|
+
const query = `CREATE TABLE IF NOT EXISTS ${quoteIdent(tableName)} (${columns})`;
|
|
322
362
|
await this.execute(query);
|
|
323
363
|
}
|
|
324
364
|
async dropTable(tableName) {
|
|
325
|
-
const query = `DROP TABLE IF EXISTS ${tableName}`;
|
|
365
|
+
const query = `DROP TABLE IF EXISTS ${quoteIdent(tableName)}`;
|
|
326
366
|
await this.execute(query);
|
|
327
367
|
}
|
|
328
368
|
/**
|
|
@@ -351,18 +391,17 @@ var DatabaseAPI = class {
|
|
|
351
391
|
async insert(tableName, data) {
|
|
352
392
|
const keys = Object.keys(data);
|
|
353
393
|
const values = Object.values(data);
|
|
394
|
+
const quotedCols = keys.map(quoteIdent).join(", ");
|
|
354
395
|
const placeholders = keys.map(() => "?").join(", ");
|
|
355
|
-
const query = `INSERT INTO ${tableName} (${
|
|
356
|
-
", "
|
|
357
|
-
)}) VALUES (${placeholders})`;
|
|
396
|
+
const query = `INSERT INTO ${quoteIdent(tableName)} (${quotedCols}) VALUES (${placeholders})`;
|
|
358
397
|
const result = await this.execute(query, values);
|
|
359
398
|
return result.lastInsertId ?? -1;
|
|
360
399
|
}
|
|
361
400
|
async update(tableName, data, where, whereParams) {
|
|
362
401
|
const keys = Object.keys(data);
|
|
363
402
|
const values = Object.values(data);
|
|
364
|
-
const setClause = keys.map((key) => `${key} = ?`).join(", ");
|
|
365
|
-
const query = `UPDATE ${tableName} SET ${setClause} WHERE ${where}`;
|
|
403
|
+
const setClause = keys.map((key) => `${quoteIdent(key)} = ?`).join(", ");
|
|
404
|
+
const query = `UPDATE ${quoteIdent(tableName)} SET ${setClause} WHERE ${where}`;
|
|
366
405
|
const result = await this.execute(query, [
|
|
367
406
|
...values,
|
|
368
407
|
...whereParams || []
|
|
@@ -370,12 +409,12 @@ var DatabaseAPI = class {
|
|
|
370
409
|
return result.rowsAffected;
|
|
371
410
|
}
|
|
372
411
|
async delete(tableName, where, whereParams) {
|
|
373
|
-
const query = `DELETE FROM ${tableName} WHERE ${where}`;
|
|
412
|
+
const query = `DELETE FROM ${quoteIdent(tableName)} WHERE ${where}`;
|
|
374
413
|
const result = await this.execute(query, whereParams);
|
|
375
414
|
return result.rowsAffected;
|
|
376
415
|
}
|
|
377
416
|
async count(tableName, where, whereParams) {
|
|
378
|
-
const query = where ? `SELECT COUNT(*) as count FROM ${tableName} WHERE ${where}` : `SELECT COUNT(*) as count FROM ${tableName}`;
|
|
417
|
+
const query = where ? `SELECT COUNT(*) as count FROM ${quoteIdent(tableName)} WHERE ${where}` : `SELECT COUNT(*) as count FROM ${quoteIdent(tableName)}`;
|
|
379
418
|
const result = await this.queryOne(query, whereParams);
|
|
380
419
|
return result?.count ?? 0;
|
|
381
420
|
}
|
|
@@ -1222,12 +1261,163 @@ var ShellAPI = class {
|
|
|
1222
1261
|
}
|
|
1223
1262
|
};
|
|
1224
1263
|
|
|
1264
|
+
// src/api/passwords.ts
|
|
1265
|
+
var PasswordsAPI = class {
|
|
1266
|
+
constructor(client) {
|
|
1267
|
+
this.client = client;
|
|
1268
|
+
}
|
|
1269
|
+
/** List items in scope — summaries only, no secrets. */
|
|
1270
|
+
async listAsync() {
|
|
1271
|
+
return this.client.request(
|
|
1272
|
+
PASSWORD_COMMANDS.list,
|
|
1273
|
+
{}
|
|
1274
|
+
);
|
|
1275
|
+
}
|
|
1276
|
+
/** Read a single item by id with full secrets. */
|
|
1277
|
+
async readAsync(itemId) {
|
|
1278
|
+
return this.client.request(PASSWORD_COMMANDS.read, {
|
|
1279
|
+
itemId
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Create a new password item. `input.tags` must contain at least one
|
|
1284
|
+
* tag within the extension's permission scope, otherwise the write
|
|
1285
|
+
* is rejected as a security violation.
|
|
1286
|
+
*
|
|
1287
|
+
* Returns the new item id.
|
|
1288
|
+
*/
|
|
1289
|
+
async createAsync(input) {
|
|
1290
|
+
return this.client.request(PASSWORD_COMMANDS.create, { input });
|
|
1291
|
+
}
|
|
1292
|
+
/**
|
|
1293
|
+
* Update an existing item. The item must already be in scope, and
|
|
1294
|
+
* the new tag set must keep at least one tag in scope (extensions
|
|
1295
|
+
* cannot orphan an item out of their own reach).
|
|
1296
|
+
*/
|
|
1297
|
+
async updateAsync(itemId, input) {
|
|
1298
|
+
return this.client.request(PASSWORD_COMMANDS.update, {
|
|
1299
|
+
itemId,
|
|
1300
|
+
input
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
/** Delete an item by id. Item must be in scope. */
|
|
1304
|
+
async deleteAsync(itemId) {
|
|
1305
|
+
return this.client.request(PASSWORD_COMMANDS.delete, { itemId });
|
|
1306
|
+
}
|
|
1307
|
+
};
|
|
1308
|
+
|
|
1309
|
+
// src/api/mail.ts
|
|
1310
|
+
var MailAPI = class {
|
|
1311
|
+
constructor(client) {
|
|
1312
|
+
this.client = client;
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* LIST mailboxes for an IMAP account. Pass `includeStatus=true` for
|
|
1316
|
+
* EXISTS/UNSEEN/UIDVALIDITY/UIDNEXT per box (one extra round-trip
|
|
1317
|
+
* per mailbox — fine for typical accounts, expensive for large
|
|
1318
|
+
* trees).
|
|
1319
|
+
*/
|
|
1320
|
+
async listMailboxesAsync(imap, options = {}) {
|
|
1321
|
+
return this.client.request(MAIL_COMMANDS.listMailboxes, {
|
|
1322
|
+
imap,
|
|
1323
|
+
reference: options.reference,
|
|
1324
|
+
pattern: options.pattern,
|
|
1325
|
+
includeStatus: options.includeStatus
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
/** Fetch lightweight envelopes for a mailbox + range (for list views). */
|
|
1329
|
+
async fetchEnvelopesAsync(imap, mailbox, range) {
|
|
1330
|
+
return this.client.request(
|
|
1331
|
+
MAIL_COMMANDS.fetchEnvelopes,
|
|
1332
|
+
{ imap, mailbox, range }
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
/** Fetch a full message (envelope + body + attachment metadata) by UID. */
|
|
1336
|
+
async fetchMessageAsync(imap, mailbox, uid) {
|
|
1337
|
+
return this.client.request(MAIL_COMMANDS.fetchMessage, {
|
|
1338
|
+
imap,
|
|
1339
|
+
mailbox,
|
|
1340
|
+
uid
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Set or unset IMAP flags. Use `flags=["\\Seen"]` + `add=true` to
|
|
1345
|
+
* mark messages as read; `add=false` removes the flag(s).
|
|
1346
|
+
*/
|
|
1347
|
+
async setFlagsAsync(imap, mailbox, uids, flags, add) {
|
|
1348
|
+
return this.client.request(MAIL_COMMANDS.setFlags, {
|
|
1349
|
+
imap,
|
|
1350
|
+
mailbox,
|
|
1351
|
+
uids,
|
|
1352
|
+
flags,
|
|
1353
|
+
add
|
|
1354
|
+
});
|
|
1355
|
+
}
|
|
1356
|
+
/** Move messages between mailboxes. Falls back to COPY+EXPUNGE on servers without MOVE. */
|
|
1357
|
+
async moveMessagesAsync(imap, sourceMailbox, destinationMailbox, uids) {
|
|
1358
|
+
return this.client.request(MAIL_COMMANDS.moveMessages, {
|
|
1359
|
+
imap,
|
|
1360
|
+
sourceMailbox,
|
|
1361
|
+
destinationMailbox,
|
|
1362
|
+
uids
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
/**
|
|
1366
|
+
* APPEND a base64-encoded RFC822 message into a mailbox. Combine
|
|
1367
|
+
* with `buildRfc822Async` to save drafts, or with the bytes returned
|
|
1368
|
+
* after `sendMessageAsync` to mirror the sent copy into "Sent".
|
|
1369
|
+
*/
|
|
1370
|
+
async appendMessageAsync(imap, mailbox, rfc822Base64, flags) {
|
|
1371
|
+
return this.client.request(MAIL_COMMANDS.appendMessage, {
|
|
1372
|
+
imap,
|
|
1373
|
+
mailbox,
|
|
1374
|
+
rfc822Base64,
|
|
1375
|
+
flags
|
|
1376
|
+
});
|
|
1377
|
+
}
|
|
1378
|
+
/** Send a message via SMTP. Returns the assigned Message-ID (no angle brackets). */
|
|
1379
|
+
async sendMessageAsync(smtp, message) {
|
|
1380
|
+
return this.client.request(MAIL_COMMANDS.sendMessage, {
|
|
1381
|
+
smtp,
|
|
1382
|
+
message
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Build RFC822 bytes for a message without sending — useful for
|
|
1387
|
+
* drafts that get APPENDed to a "Drafts" folder. Permission-wise
|
|
1388
|
+
* this is a fetch operation (no SMTP host involved).
|
|
1389
|
+
*/
|
|
1390
|
+
async buildRfc822Async(imapHost, message) {
|
|
1391
|
+
return this.client.request(MAIL_COMMANDS.buildRfc822, {
|
|
1392
|
+
imapHost,
|
|
1393
|
+
message
|
|
1394
|
+
});
|
|
1395
|
+
}
|
|
1396
|
+
};
|
|
1397
|
+
|
|
1225
1398
|
// src/messages.ts
|
|
1226
1399
|
var HAEXSPACE_MESSAGE_TYPES = {
|
|
1227
1400
|
/** Debug message for development/troubleshooting */
|
|
1228
1401
|
DEBUG: "haexspace:debug",
|
|
1229
1402
|
/** Console forwarding from extension iframe */
|
|
1230
|
-
CONSOLE_FORWARD: "console.forward"
|
|
1403
|
+
CONSOLE_FORWARD: "console.forward",
|
|
1404
|
+
/**
|
|
1405
|
+
* Sent from main window to iframe on the shared window listener, carrying
|
|
1406
|
+
* one `MessagePort` in `event.ports[0]`. Once received, the SDK switches
|
|
1407
|
+
* to port-based messaging and never reads the window listener again.
|
|
1408
|
+
*
|
|
1409
|
+
* Payload: `{ type: PORT_INIT }` — no data. The port itself is the payload.
|
|
1410
|
+
*/
|
|
1411
|
+
PORT_INIT: "haexspace:port:init",
|
|
1412
|
+
/**
|
|
1413
|
+
* Sent from SDK to main window *over the MessagePort* after the port is
|
|
1414
|
+
* installed. Main uses this to mark the iframe as ready and flush any
|
|
1415
|
+
* events buffered during the handshake window. Only valid on the port —
|
|
1416
|
+
* a READY sent over window.postMessage is ignored.
|
|
1417
|
+
*
|
|
1418
|
+
* Payload: `{ type: PORT_READY }` — no data.
|
|
1419
|
+
*/
|
|
1420
|
+
PORT_READY: "haexspace:port:ready"
|
|
1231
1421
|
};
|
|
1232
1422
|
|
|
1233
1423
|
// src/polyfills/consoleForwarding.ts
|
|
@@ -1382,6 +1572,7 @@ function parseTableName(fullTableName) {
|
|
|
1382
1572
|
}
|
|
1383
1573
|
|
|
1384
1574
|
// src/client/init.ts
|
|
1575
|
+
var PORT_HANDSHAKE_TIMEOUT_MS = 1e4;
|
|
1385
1576
|
function isInIframe() {
|
|
1386
1577
|
return window.self !== window.top;
|
|
1387
1578
|
}
|
|
@@ -1638,17 +1829,20 @@ async function initIframeMode(ctx, log, messageHandler, request) {
|
|
|
1638
1829
|
if (!isInIframe()) {
|
|
1639
1830
|
throw new HaexVaultSdkError("NOT_IN_IFRAME" /* NOT_IN_IFRAME */, "errors.not_in_iframe");
|
|
1640
1831
|
}
|
|
1832
|
+
const port = await waitForHostPortAsync(log);
|
|
1641
1833
|
ctx.handlers.messageHandler = messageHandler;
|
|
1642
|
-
|
|
1834
|
+
port.addEventListener("message", messageHandler);
|
|
1835
|
+
port.start();
|
|
1836
|
+
port.postMessage({ type: HAEXSPACE_MESSAGE_TYPES.PORT_READY });
|
|
1643
1837
|
ctx.state.isNativeWindow = false;
|
|
1644
1838
|
ctx.state.initialized = true;
|
|
1645
|
-
log("HaexVault SDK initialized in iframe mode");
|
|
1839
|
+
log("HaexVault SDK initialized in iframe mode (MessagePort transport)");
|
|
1646
1840
|
if (ctx.config.manifest) {
|
|
1647
1841
|
ctx.state.extensionInfo = {
|
|
1648
1842
|
publicKey: ctx.config.manifest.publicKey,
|
|
1649
1843
|
name: ctx.config.manifest.name,
|
|
1650
1844
|
version: ctx.config.manifest.version,
|
|
1651
|
-
displayName: ctx.config.manifest.name
|
|
1845
|
+
displayName: ctx.config.manifest.displayName ?? ctx.config.manifest.name
|
|
1652
1846
|
};
|
|
1653
1847
|
log("Extension info loaded from manifest:", ctx.state.extensionInfo);
|
|
1654
1848
|
}
|
|
@@ -1656,7 +1850,42 @@ async function initIframeMode(ctx, log, messageHandler, request) {
|
|
|
1656
1850
|
const context = await request(EXTENSION_COMMANDS.getContext);
|
|
1657
1851
|
ctx.state.context = context;
|
|
1658
1852
|
log("Application context received:", context);
|
|
1659
|
-
return { context };
|
|
1853
|
+
return { context, port };
|
|
1854
|
+
}
|
|
1855
|
+
function waitForHostPortAsync(log) {
|
|
1856
|
+
return new Promise((resolve, reject) => {
|
|
1857
|
+
let settled = false;
|
|
1858
|
+
const cleanup = () => {
|
|
1859
|
+
window.removeEventListener("message", handler);
|
|
1860
|
+
};
|
|
1861
|
+
const timeoutId = setTimeout(() => {
|
|
1862
|
+
if (settled) return;
|
|
1863
|
+
settled = true;
|
|
1864
|
+
cleanup();
|
|
1865
|
+
reject(
|
|
1866
|
+
new HaexVaultSdkError(
|
|
1867
|
+
"TIMEOUT" /* TIMEOUT */,
|
|
1868
|
+
"errors.port_handshake_timeout",
|
|
1869
|
+
{ timeout: PORT_HANDSHAKE_TIMEOUT_MS }
|
|
1870
|
+
)
|
|
1871
|
+
);
|
|
1872
|
+
}, PORT_HANDSHAKE_TIMEOUT_MS);
|
|
1873
|
+
const handler = (event) => {
|
|
1874
|
+
const type = event.data?.type;
|
|
1875
|
+
if (type !== HAEXSPACE_MESSAGE_TYPES.PORT_INIT) return;
|
|
1876
|
+
const port = event.ports[0];
|
|
1877
|
+
if (!port) {
|
|
1878
|
+
log("PORT_INIT received but event.ports is empty \u2014 ignoring");
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1881
|
+
if (settled) return;
|
|
1882
|
+
settled = true;
|
|
1883
|
+
clearTimeout(timeoutId);
|
|
1884
|
+
cleanup();
|
|
1885
|
+
resolve(port);
|
|
1886
|
+
};
|
|
1887
|
+
window.addEventListener("message", handler);
|
|
1888
|
+
});
|
|
1660
1889
|
}
|
|
1661
1890
|
function sendDebugInfo(config) {
|
|
1662
1891
|
if (!config.debug) return;
|
|
@@ -1680,7 +1909,15 @@ postMessage error: ${e}`);
|
|
|
1680
1909
|
function generateRequestId(counter) {
|
|
1681
1910
|
return `req_${counter}`;
|
|
1682
1911
|
}
|
|
1683
|
-
function sendPostMessage(method, params, requestId, config, extensionInfo, pendingRequests) {
|
|
1912
|
+
function sendPostMessage(method, params, requestId, config, extensionInfo, pendingRequests, port) {
|
|
1913
|
+
if (!port) {
|
|
1914
|
+
return Promise.reject(
|
|
1915
|
+
new HaexVaultSdkError(
|
|
1916
|
+
"EXTENSION_NOT_INITIALIZED" /* EXTENSION_NOT_INITIALIZED */,
|
|
1917
|
+
"errors.port_not_connected"
|
|
1918
|
+
)
|
|
1919
|
+
);
|
|
1920
|
+
}
|
|
1684
1921
|
const request = {
|
|
1685
1922
|
method,
|
|
1686
1923
|
params,
|
|
@@ -1696,17 +1933,16 @@ function sendPostMessage(method, params, requestId, config, extensionInfo, pendi
|
|
|
1696
1933
|
);
|
|
1697
1934
|
}, config.timeout);
|
|
1698
1935
|
pendingRequests.set(requestId, { resolve, reject, timeout });
|
|
1699
|
-
const targetOrigin = "*";
|
|
1700
1936
|
if (config.debug) {
|
|
1701
1937
|
console.log("[SDK Debug] ========== Sending Request ==========");
|
|
1702
1938
|
console.log("[SDK Debug] Request ID:", requestId);
|
|
1703
1939
|
console.log("[SDK Debug] Method:", request.method);
|
|
1704
1940
|
console.log("[SDK Debug] Params:", request.params);
|
|
1705
|
-
console.log("[SDK Debug]
|
|
1941
|
+
console.log("[SDK Debug] Transport: MessagePort");
|
|
1706
1942
|
console.log("[SDK Debug] Extension info:", extensionInfo);
|
|
1707
1943
|
console.log("[SDK Debug] ========================================");
|
|
1708
1944
|
}
|
|
1709
|
-
|
|
1945
|
+
port.postMessage({ id: requestId, ...request });
|
|
1710
1946
|
});
|
|
1711
1947
|
}
|
|
1712
1948
|
async function sendInvoke(method, params, config, _log) {
|
|
@@ -1725,11 +1961,6 @@ function createMessageHandler(config, pendingRequests, extensionInfo, onEvent) {
|
|
|
1725
1961
|
return (event) => {
|
|
1726
1962
|
if (config.debug) {
|
|
1727
1963
|
console.log("[SDK Debug] ========== Message Received ==========");
|
|
1728
|
-
console.log("[SDK Debug] Event origin:", event.origin);
|
|
1729
|
-
console.log(
|
|
1730
|
-
"[SDK Debug] Event source:",
|
|
1731
|
-
event.source === window.parent ? "parent window" : "unknown"
|
|
1732
|
-
);
|
|
1733
1964
|
console.log("[SDK Debug] Event data:", event.data);
|
|
1734
1965
|
console.log("[SDK Debug] Extension info loaded:", !!extensionInfo());
|
|
1735
1966
|
console.log(
|
|
@@ -1737,12 +1968,6 @@ function createMessageHandler(config, pendingRequests, extensionInfo, onEvent) {
|
|
|
1737
1968
|
pendingRequests.size
|
|
1738
1969
|
);
|
|
1739
1970
|
}
|
|
1740
|
-
if (event.source !== window.parent) {
|
|
1741
|
-
if (config.debug) {
|
|
1742
|
-
console.error("[SDK Debug] \u274C REJECTED: Message not from parent window!");
|
|
1743
|
-
}
|
|
1744
|
-
return;
|
|
1745
|
-
}
|
|
1746
1971
|
const data = event.data;
|
|
1747
1972
|
if ("id" in data && pendingRequests.has(data.id)) {
|
|
1748
1973
|
if (config.debug) {
|
|
@@ -1808,11 +2033,10 @@ function processEvent(event, log, eventListeners, onContextChanged, onExternalRe
|
|
|
1808
2033
|
emitEvent(event, log, eventListeners);
|
|
1809
2034
|
}
|
|
1810
2035
|
function emitEvent(event, log, eventListeners) {
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
log("Event received:", event);
|
|
2036
|
+
log("emitEvent called with:", event.type, event);
|
|
2037
|
+
log("Registered event types:", Array.from(eventListeners.keys()));
|
|
1814
2038
|
const listeners = eventListeners.get(event.type);
|
|
1815
|
-
|
|
2039
|
+
log("Listeners for", event.type, ":", listeners?.size ?? 0);
|
|
1816
2040
|
if (listeners) {
|
|
1817
2041
|
listeners.forEach((callback) => callback(event));
|
|
1818
2042
|
}
|
|
@@ -1909,9 +2133,9 @@ function registerExternalHandler(action, handler, handlers, log) {
|
|
|
1909
2133
|
};
|
|
1910
2134
|
}
|
|
1911
2135
|
async function handleExternalRequest(request, handlers, respond, log) {
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
2136
|
+
log("handleExternalRequest called");
|
|
2137
|
+
log("Request:", request);
|
|
2138
|
+
log("Available handlers:", Array.from(handlers.keys()));
|
|
1915
2139
|
log(`[ExternalRequest] Received request: ${request.action} from ${request.publicKey.substring(0, 20)}...`);
|
|
1916
2140
|
const handler = handlers.get(request.action);
|
|
1917
2141
|
if (!handler) {
|
|
@@ -1937,7 +2161,6 @@ async function handleExternalRequest(request, handlers, respond, log) {
|
|
|
1937
2161
|
}
|
|
1938
2162
|
}
|
|
1939
2163
|
async function respondToExternalRequest(response, request) {
|
|
1940
|
-
console.log("[SDK Debug] respondToExternalRequest called with:", JSON.stringify(response, null, 2));
|
|
1941
2164
|
await request(EXTERNAL_BRIDGE_COMMANDS.respond, response);
|
|
1942
2165
|
}
|
|
1943
2166
|
|
|
@@ -1964,6 +2187,13 @@ var HaexVaultSdk = class {
|
|
|
1964
2187
|
this.reactiveSubscribers = /* @__PURE__ */ new Set();
|
|
1965
2188
|
// Handlers
|
|
1966
2189
|
this.messageHandler = null;
|
|
2190
|
+
/**
|
|
2191
|
+
* MessagePort obtained from the main window during iframe-mode handshake.
|
|
2192
|
+
* `null` until `initIframe()` completes successfully. Every outbound
|
|
2193
|
+
* request in iframe mode flows through this port; `sendPostMessage` rejects
|
|
2194
|
+
* if called before the handshake finishes.
|
|
2195
|
+
*/
|
|
2196
|
+
this.hostPort = null;
|
|
1967
2197
|
this.setupPromise = null;
|
|
1968
2198
|
this.setupHook = null;
|
|
1969
2199
|
// Public APIs
|
|
@@ -1988,11 +2218,17 @@ var HaexVaultSdk = class {
|
|
|
1988
2218
|
this.localsend = new LocalSendAPI(this);
|
|
1989
2219
|
this.spaces = new SpacesAPI(this);
|
|
1990
2220
|
this.shell = new ShellAPI(this);
|
|
2221
|
+
this.passwords = new PasswordsAPI(this);
|
|
2222
|
+
this.mail = new MailAPI(this);
|
|
1991
2223
|
installConsoleForwarding(this.config.debug);
|
|
1992
|
-
this.readyPromise = new Promise((resolve) => {
|
|
2224
|
+
this.readyPromise = new Promise((resolve, reject) => {
|
|
1993
2225
|
this.resolveReady = resolve;
|
|
2226
|
+
this.rejectReady = reject;
|
|
2227
|
+
});
|
|
2228
|
+
this.init().catch((error) => {
|
|
2229
|
+
this.log("Init failed:", error);
|
|
2230
|
+
this.rejectReady(error);
|
|
1994
2231
|
});
|
|
1995
|
-
this.init();
|
|
1996
2232
|
}
|
|
1997
2233
|
// ==========================================================================
|
|
1998
2234
|
// Lifecycle
|
|
@@ -2020,9 +2256,14 @@ var HaexVaultSdk = class {
|
|
|
2020
2256
|
return this.setupPromise;
|
|
2021
2257
|
}
|
|
2022
2258
|
destroy() {
|
|
2023
|
-
if (this.messageHandler) {
|
|
2024
|
-
|
|
2259
|
+
if (this.messageHandler && this.hostPort) {
|
|
2260
|
+
this.hostPort.removeEventListener("message", this.messageHandler);
|
|
2025
2261
|
}
|
|
2262
|
+
if (this.hostPort) {
|
|
2263
|
+
this.hostPort.close();
|
|
2264
|
+
this.hostPort = null;
|
|
2265
|
+
}
|
|
2266
|
+
this.messageHandler = null;
|
|
2026
2267
|
this.pendingRequests.forEach(({ timeout }) => clearTimeout(timeout));
|
|
2027
2268
|
this.pendingRequests.clear();
|
|
2028
2269
|
this.eventListeners.clear();
|
|
@@ -2137,7 +2378,15 @@ var HaexVaultSdk = class {
|
|
|
2137
2378
|
return sendInvoke(method, paramsWithCredentials, this.config, this.log.bind(this));
|
|
2138
2379
|
}
|
|
2139
2380
|
const requestId = generateRequestId(++this.requestCounter);
|
|
2140
|
-
return sendPostMessage(
|
|
2381
|
+
return sendPostMessage(
|
|
2382
|
+
method,
|
|
2383
|
+
resolvedParams,
|
|
2384
|
+
requestId,
|
|
2385
|
+
this.config,
|
|
2386
|
+
this._extensionInfo,
|
|
2387
|
+
this.pendingRequests,
|
|
2388
|
+
this.hostPort
|
|
2389
|
+
);
|
|
2141
2390
|
}
|
|
2142
2391
|
// ==========================================================================
|
|
2143
2392
|
// Private: Initialization
|
|
@@ -2204,7 +2453,7 @@ var HaexVaultSdk = class {
|
|
|
2204
2453
|
() => this._extensionInfo,
|
|
2205
2454
|
this.handleEvent.bind(this)
|
|
2206
2455
|
);
|
|
2207
|
-
const { context } = await initIframeMode(
|
|
2456
|
+
const { context, port } = await initIframeMode(
|
|
2208
2457
|
{
|
|
2209
2458
|
config: this.config,
|
|
2210
2459
|
state: {
|
|
@@ -2236,12 +2485,13 @@ var HaexVaultSdk = class {
|
|
|
2236
2485
|
this.messageHandler,
|
|
2237
2486
|
this.request.bind(this)
|
|
2238
2487
|
);
|
|
2488
|
+
this.hostPort = port;
|
|
2239
2489
|
if (this.config.manifest) {
|
|
2240
2490
|
this._extensionInfo = {
|
|
2241
2491
|
publicKey: this.config.manifest.publicKey,
|
|
2242
2492
|
name: this.config.manifest.name,
|
|
2243
2493
|
version: this.config.manifest.version,
|
|
2244
|
-
displayName: this.config.manifest.name
|
|
2494
|
+
displayName: this.config.manifest.displayName ?? this.config.manifest.name
|
|
2245
2495
|
};
|
|
2246
2496
|
this.notifySubscribersInternal();
|
|
2247
2497
|
}
|
|
@@ -2323,22 +2573,18 @@ var nuxt_plugin_client_default = defineNuxtPlugin(async (nuxtApp) => {
|
|
|
2323
2573
|
context: client.context
|
|
2324
2574
|
});
|
|
2325
2575
|
await client.ready();
|
|
2326
|
-
console.log("[Nuxt Plugin] Client ready, context:", client.context);
|
|
2327
2576
|
state.value = {
|
|
2328
2577
|
isReady: true,
|
|
2329
2578
|
isSetupComplete: false,
|
|
2330
2579
|
context: client.context
|
|
2331
2580
|
};
|
|
2332
|
-
console.log("[Nuxt Plugin] Initial state set:", state.value);
|
|
2333
2581
|
client.subscribe(() => {
|
|
2334
|
-
console.log("[Nuxt Plugin] Client context updated:", client.context);
|
|
2335
2582
|
const isSetupComplete = client.setupCompleted;
|
|
2336
2583
|
state.value = {
|
|
2337
2584
|
...state.value,
|
|
2338
2585
|
context: client.context,
|
|
2339
2586
|
isSetupComplete
|
|
2340
2587
|
};
|
|
2341
|
-
console.log("[Nuxt Plugin] State updated:", state.value);
|
|
2342
2588
|
});
|
|
2343
2589
|
const haexVaultPlugin = {
|
|
2344
2590
|
client,
|