@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
package/dist/index.js
CHANGED
|
@@ -541,7 +541,24 @@ var HAEXSPACE_MESSAGE_TYPES = {
|
|
|
541
541
|
/** Debug message for development/troubleshooting */
|
|
542
542
|
DEBUG: "haexspace:debug",
|
|
543
543
|
/** Console forwarding from extension iframe */
|
|
544
|
-
CONSOLE_FORWARD: "console.forward"
|
|
544
|
+
CONSOLE_FORWARD: "console.forward",
|
|
545
|
+
/**
|
|
546
|
+
* Sent from main window to iframe on the shared window listener, carrying
|
|
547
|
+
* one `MessagePort` in `event.ports[0]`. Once received, the SDK switches
|
|
548
|
+
* to port-based messaging and never reads the window listener again.
|
|
549
|
+
*
|
|
550
|
+
* Payload: `{ type: PORT_INIT }` — no data. The port itself is the payload.
|
|
551
|
+
*/
|
|
552
|
+
PORT_INIT: "haexspace:port:init",
|
|
553
|
+
/**
|
|
554
|
+
* Sent from SDK to main window *over the MessagePort* after the port is
|
|
555
|
+
* installed. Main uses this to mark the iframe as ready and flush any
|
|
556
|
+
* events buffered during the handshake window. Only valid on the port —
|
|
557
|
+
* a READY sent over window.postMessage is ignored.
|
|
558
|
+
*
|
|
559
|
+
* Payload: `{ type: PORT_READY }` — no data.
|
|
560
|
+
*/
|
|
561
|
+
PORT_READY: "haexspace:port:ready"
|
|
545
562
|
};
|
|
546
563
|
|
|
547
564
|
// src/polyfills/debug.ts
|
|
@@ -1032,6 +1049,40 @@ var SHELL_COMMANDS = {
|
|
|
1032
1049
|
close: "extension_shell_close"
|
|
1033
1050
|
};
|
|
1034
1051
|
|
|
1052
|
+
// src/commands/passwords.ts
|
|
1053
|
+
var PASSWORD_COMMANDS = {
|
|
1054
|
+
/** List items (no secrets) within the extension's tag scope */
|
|
1055
|
+
list: "extension_password_list",
|
|
1056
|
+
/** Read full item including secrets, by id */
|
|
1057
|
+
read: "extension_password_read",
|
|
1058
|
+
/** Create item — must include >=1 tag in scope */
|
|
1059
|
+
create: "extension_password_create",
|
|
1060
|
+
/** Update item — keeps >=1 tag in scope */
|
|
1061
|
+
update: "extension_password_update",
|
|
1062
|
+
/** Delete item — must be in scope */
|
|
1063
|
+
delete: "extension_password_delete"
|
|
1064
|
+
};
|
|
1065
|
+
|
|
1066
|
+
// src/commands/mail.ts
|
|
1067
|
+
var MAIL_COMMANDS = {
|
|
1068
|
+
/** LIST mailboxes + optional STATUS counts */
|
|
1069
|
+
listMailboxes: "extension_mail_list_mailboxes",
|
|
1070
|
+
/** Lightweight envelope fetch for list views */
|
|
1071
|
+
fetchEnvelopes: "extension_mail_fetch_envelopes",
|
|
1072
|
+
/** Full message fetch (envelope + body + attachment metadata) */
|
|
1073
|
+
fetchMessage: "extension_mail_fetch_message",
|
|
1074
|
+
/** Set or unset IMAP flags on a UID set */
|
|
1075
|
+
setFlags: "extension_mail_set_flags",
|
|
1076
|
+
/** MOVE messages between mailboxes (COPY+EXPUNGE fallback) */
|
|
1077
|
+
moveMessages: "extension_mail_move_messages",
|
|
1078
|
+
/** APPEND a base64-encoded RFC822 message into a mailbox */
|
|
1079
|
+
appendMessage: "extension_mail_append_message",
|
|
1080
|
+
/** SMTP send. Returns the assigned Message-ID. */
|
|
1081
|
+
sendMessage: "extension_mail_send_message",
|
|
1082
|
+
/** Build RFC822 bytes without sending (for Drafts via APPEND) */
|
|
1083
|
+
buildRfc822: "extension_mail_build_rfc822"
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1035
1086
|
// src/commands/index.ts
|
|
1036
1087
|
var TAURI_COMMANDS = {
|
|
1037
1088
|
database: DATABASE_COMMANDS,
|
|
@@ -1044,7 +1095,9 @@ var TAURI_COMMANDS = {
|
|
|
1044
1095
|
remoteStorage: REMOTE_STORAGE_COMMANDS,
|
|
1045
1096
|
localsend: LOCALSEND_COMMANDS,
|
|
1046
1097
|
spaces: SPACE_COMMANDS,
|
|
1047
|
-
shell: SHELL_COMMANDS
|
|
1098
|
+
shell: SHELL_COMMANDS,
|
|
1099
|
+
passwords: PASSWORD_COMMANDS,
|
|
1100
|
+
mail: MAIL_COMMANDS
|
|
1048
1101
|
};
|
|
1049
1102
|
|
|
1050
1103
|
// src/api/storage.ts
|
|
@@ -1070,6 +1123,12 @@ var StorageAPI = class {
|
|
|
1070
1123
|
};
|
|
1071
1124
|
|
|
1072
1125
|
// src/api/database.ts
|
|
1126
|
+
function quoteIdent(identifier) {
|
|
1127
|
+
if (identifier.startsWith('"') && identifier.endsWith('"')) {
|
|
1128
|
+
return identifier;
|
|
1129
|
+
}
|
|
1130
|
+
return `"${identifier.replace(/"/g, '""')}"`;
|
|
1131
|
+
}
|
|
1073
1132
|
var DatabaseAPI = class {
|
|
1074
1133
|
constructor(client) {
|
|
1075
1134
|
this.client = client;
|
|
@@ -1100,11 +1159,11 @@ var DatabaseAPI = class {
|
|
|
1100
1159
|
});
|
|
1101
1160
|
}
|
|
1102
1161
|
async createTable(tableName, columns) {
|
|
1103
|
-
const query = `CREATE TABLE IF NOT EXISTS ${tableName} (${columns})`;
|
|
1162
|
+
const query = `CREATE TABLE IF NOT EXISTS ${quoteIdent(tableName)} (${columns})`;
|
|
1104
1163
|
await this.execute(query);
|
|
1105
1164
|
}
|
|
1106
1165
|
async dropTable(tableName) {
|
|
1107
|
-
const query = `DROP TABLE IF EXISTS ${tableName}`;
|
|
1166
|
+
const query = `DROP TABLE IF EXISTS ${quoteIdent(tableName)}`;
|
|
1108
1167
|
await this.execute(query);
|
|
1109
1168
|
}
|
|
1110
1169
|
/**
|
|
@@ -1133,18 +1192,17 @@ var DatabaseAPI = class {
|
|
|
1133
1192
|
async insert(tableName, data) {
|
|
1134
1193
|
const keys = Object.keys(data);
|
|
1135
1194
|
const values = Object.values(data);
|
|
1195
|
+
const quotedCols = keys.map(quoteIdent).join(", ");
|
|
1136
1196
|
const placeholders = keys.map(() => "?").join(", ");
|
|
1137
|
-
const query = `INSERT INTO ${tableName} (${
|
|
1138
|
-
", "
|
|
1139
|
-
)}) VALUES (${placeholders})`;
|
|
1197
|
+
const query = `INSERT INTO ${quoteIdent(tableName)} (${quotedCols}) VALUES (${placeholders})`;
|
|
1140
1198
|
const result = await this.execute(query, values);
|
|
1141
1199
|
return result.lastInsertId ?? -1;
|
|
1142
1200
|
}
|
|
1143
1201
|
async update(tableName, data, where, whereParams) {
|
|
1144
1202
|
const keys = Object.keys(data);
|
|
1145
1203
|
const values = Object.values(data);
|
|
1146
|
-
const setClause = keys.map((key) => `${key} = ?`).join(", ");
|
|
1147
|
-
const query = `UPDATE ${tableName} SET ${setClause} WHERE ${where}`;
|
|
1204
|
+
const setClause = keys.map((key) => `${quoteIdent(key)} = ?`).join(", ");
|
|
1205
|
+
const query = `UPDATE ${quoteIdent(tableName)} SET ${setClause} WHERE ${where}`;
|
|
1148
1206
|
const result = await this.execute(query, [
|
|
1149
1207
|
...values,
|
|
1150
1208
|
...whereParams || []
|
|
@@ -1152,12 +1210,12 @@ var DatabaseAPI = class {
|
|
|
1152
1210
|
return result.rowsAffected;
|
|
1153
1211
|
}
|
|
1154
1212
|
async delete(tableName, where, whereParams) {
|
|
1155
|
-
const query = `DELETE FROM ${tableName} WHERE ${where}`;
|
|
1213
|
+
const query = `DELETE FROM ${quoteIdent(tableName)} WHERE ${where}`;
|
|
1156
1214
|
const result = await this.execute(query, whereParams);
|
|
1157
1215
|
return result.rowsAffected;
|
|
1158
1216
|
}
|
|
1159
1217
|
async count(tableName, where, whereParams) {
|
|
1160
|
-
const query = where ? `SELECT COUNT(*) as count FROM ${tableName} WHERE ${where}` : `SELECT COUNT(*) as count FROM ${tableName}`;
|
|
1218
|
+
const query = where ? `SELECT COUNT(*) as count FROM ${quoteIdent(tableName)} WHERE ${where}` : `SELECT COUNT(*) as count FROM ${quoteIdent(tableName)}`;
|
|
1161
1219
|
const result = await this.queryOne(query, whereParams);
|
|
1162
1220
|
return result?.count ?? 0;
|
|
1163
1221
|
}
|
|
@@ -1988,6 +2046,140 @@ var ShellAPI = class {
|
|
|
1988
2046
|
}
|
|
1989
2047
|
};
|
|
1990
2048
|
|
|
2049
|
+
// src/api/passwords.ts
|
|
2050
|
+
var PasswordsAPI = class {
|
|
2051
|
+
constructor(client) {
|
|
2052
|
+
this.client = client;
|
|
2053
|
+
}
|
|
2054
|
+
/** List items in scope — summaries only, no secrets. */
|
|
2055
|
+
async listAsync() {
|
|
2056
|
+
return this.client.request(
|
|
2057
|
+
PASSWORD_COMMANDS.list,
|
|
2058
|
+
{}
|
|
2059
|
+
);
|
|
2060
|
+
}
|
|
2061
|
+
/** Read a single item by id with full secrets. */
|
|
2062
|
+
async readAsync(itemId) {
|
|
2063
|
+
return this.client.request(PASSWORD_COMMANDS.read, {
|
|
2064
|
+
itemId
|
|
2065
|
+
});
|
|
2066
|
+
}
|
|
2067
|
+
/**
|
|
2068
|
+
* Create a new password item. `input.tags` must contain at least one
|
|
2069
|
+
* tag within the extension's permission scope, otherwise the write
|
|
2070
|
+
* is rejected as a security violation.
|
|
2071
|
+
*
|
|
2072
|
+
* Returns the new item id.
|
|
2073
|
+
*/
|
|
2074
|
+
async createAsync(input) {
|
|
2075
|
+
return this.client.request(PASSWORD_COMMANDS.create, { input });
|
|
2076
|
+
}
|
|
2077
|
+
/**
|
|
2078
|
+
* Update an existing item. The item must already be in scope, and
|
|
2079
|
+
* the new tag set must keep at least one tag in scope (extensions
|
|
2080
|
+
* cannot orphan an item out of their own reach).
|
|
2081
|
+
*/
|
|
2082
|
+
async updateAsync(itemId, input) {
|
|
2083
|
+
return this.client.request(PASSWORD_COMMANDS.update, {
|
|
2084
|
+
itemId,
|
|
2085
|
+
input
|
|
2086
|
+
});
|
|
2087
|
+
}
|
|
2088
|
+
/** Delete an item by id. Item must be in scope. */
|
|
2089
|
+
async deleteAsync(itemId) {
|
|
2090
|
+
return this.client.request(PASSWORD_COMMANDS.delete, { itemId });
|
|
2091
|
+
}
|
|
2092
|
+
};
|
|
2093
|
+
|
|
2094
|
+
// src/api/mail.ts
|
|
2095
|
+
var MailAPI = class {
|
|
2096
|
+
constructor(client) {
|
|
2097
|
+
this.client = client;
|
|
2098
|
+
}
|
|
2099
|
+
/**
|
|
2100
|
+
* LIST mailboxes for an IMAP account. Pass `includeStatus=true` for
|
|
2101
|
+
* EXISTS/UNSEEN/UIDVALIDITY/UIDNEXT per box (one extra round-trip
|
|
2102
|
+
* per mailbox — fine for typical accounts, expensive for large
|
|
2103
|
+
* trees).
|
|
2104
|
+
*/
|
|
2105
|
+
async listMailboxesAsync(imap, options = {}) {
|
|
2106
|
+
return this.client.request(MAIL_COMMANDS.listMailboxes, {
|
|
2107
|
+
imap,
|
|
2108
|
+
reference: options.reference,
|
|
2109
|
+
pattern: options.pattern,
|
|
2110
|
+
includeStatus: options.includeStatus
|
|
2111
|
+
});
|
|
2112
|
+
}
|
|
2113
|
+
/** Fetch lightweight envelopes for a mailbox + range (for list views). */
|
|
2114
|
+
async fetchEnvelopesAsync(imap, mailbox, range) {
|
|
2115
|
+
return this.client.request(
|
|
2116
|
+
MAIL_COMMANDS.fetchEnvelopes,
|
|
2117
|
+
{ imap, mailbox, range }
|
|
2118
|
+
);
|
|
2119
|
+
}
|
|
2120
|
+
/** Fetch a full message (envelope + body + attachment metadata) by UID. */
|
|
2121
|
+
async fetchMessageAsync(imap, mailbox, uid) {
|
|
2122
|
+
return this.client.request(MAIL_COMMANDS.fetchMessage, {
|
|
2123
|
+
imap,
|
|
2124
|
+
mailbox,
|
|
2125
|
+
uid
|
|
2126
|
+
});
|
|
2127
|
+
}
|
|
2128
|
+
/**
|
|
2129
|
+
* Set or unset IMAP flags. Use `flags=["\\Seen"]` + `add=true` to
|
|
2130
|
+
* mark messages as read; `add=false` removes the flag(s).
|
|
2131
|
+
*/
|
|
2132
|
+
async setFlagsAsync(imap, mailbox, uids, flags, add) {
|
|
2133
|
+
return this.client.request(MAIL_COMMANDS.setFlags, {
|
|
2134
|
+
imap,
|
|
2135
|
+
mailbox,
|
|
2136
|
+
uids,
|
|
2137
|
+
flags,
|
|
2138
|
+
add
|
|
2139
|
+
});
|
|
2140
|
+
}
|
|
2141
|
+
/** Move messages between mailboxes. Falls back to COPY+EXPUNGE on servers without MOVE. */
|
|
2142
|
+
async moveMessagesAsync(imap, sourceMailbox, destinationMailbox, uids) {
|
|
2143
|
+
return this.client.request(MAIL_COMMANDS.moveMessages, {
|
|
2144
|
+
imap,
|
|
2145
|
+
sourceMailbox,
|
|
2146
|
+
destinationMailbox,
|
|
2147
|
+
uids
|
|
2148
|
+
});
|
|
2149
|
+
}
|
|
2150
|
+
/**
|
|
2151
|
+
* APPEND a base64-encoded RFC822 message into a mailbox. Combine
|
|
2152
|
+
* with `buildRfc822Async` to save drafts, or with the bytes returned
|
|
2153
|
+
* after `sendMessageAsync` to mirror the sent copy into "Sent".
|
|
2154
|
+
*/
|
|
2155
|
+
async appendMessageAsync(imap, mailbox, rfc822Base64, flags) {
|
|
2156
|
+
return this.client.request(MAIL_COMMANDS.appendMessage, {
|
|
2157
|
+
imap,
|
|
2158
|
+
mailbox,
|
|
2159
|
+
rfc822Base64,
|
|
2160
|
+
flags
|
|
2161
|
+
});
|
|
2162
|
+
}
|
|
2163
|
+
/** Send a message via SMTP. Returns the assigned Message-ID (no angle brackets). */
|
|
2164
|
+
async sendMessageAsync(smtp, message) {
|
|
2165
|
+
return this.client.request(MAIL_COMMANDS.sendMessage, {
|
|
2166
|
+
smtp,
|
|
2167
|
+
message
|
|
2168
|
+
});
|
|
2169
|
+
}
|
|
2170
|
+
/**
|
|
2171
|
+
* Build RFC822 bytes for a message without sending — useful for
|
|
2172
|
+
* drafts that get APPENDed to a "Drafts" folder. Permission-wise
|
|
2173
|
+
* this is a fetch operation (no SMTP host involved).
|
|
2174
|
+
*/
|
|
2175
|
+
async buildRfc822Async(imapHost, message) {
|
|
2176
|
+
return this.client.request(MAIL_COMMANDS.buildRfc822, {
|
|
2177
|
+
imapHost,
|
|
2178
|
+
message
|
|
2179
|
+
});
|
|
2180
|
+
}
|
|
2181
|
+
};
|
|
2182
|
+
|
|
1991
2183
|
// src/client/tableName.ts
|
|
1992
2184
|
function validatePublicKey(publicKey) {
|
|
1993
2185
|
if (!publicKey || typeof publicKey !== "string" || publicKey.trim() === "") {
|
|
@@ -2074,6 +2266,7 @@ function parseTableName(fullTableName) {
|
|
|
2074
2266
|
}
|
|
2075
2267
|
|
|
2076
2268
|
// src/client/init.ts
|
|
2269
|
+
var PORT_HANDSHAKE_TIMEOUT_MS = 1e4;
|
|
2077
2270
|
function isInIframe() {
|
|
2078
2271
|
return window.self !== window.top;
|
|
2079
2272
|
}
|
|
@@ -2330,17 +2523,20 @@ async function initIframeMode(ctx, log, messageHandler, request) {
|
|
|
2330
2523
|
if (!isInIframe()) {
|
|
2331
2524
|
throw new HaexVaultSdkError("NOT_IN_IFRAME" /* NOT_IN_IFRAME */, "errors.not_in_iframe");
|
|
2332
2525
|
}
|
|
2526
|
+
const port = await waitForHostPortAsync(log);
|
|
2333
2527
|
ctx.handlers.messageHandler = messageHandler;
|
|
2334
|
-
|
|
2528
|
+
port.addEventListener("message", messageHandler);
|
|
2529
|
+
port.start();
|
|
2530
|
+
port.postMessage({ type: HAEXSPACE_MESSAGE_TYPES.PORT_READY });
|
|
2335
2531
|
ctx.state.isNativeWindow = false;
|
|
2336
2532
|
ctx.state.initialized = true;
|
|
2337
|
-
log("HaexVault SDK initialized in iframe mode");
|
|
2533
|
+
log("HaexVault SDK initialized in iframe mode (MessagePort transport)");
|
|
2338
2534
|
if (ctx.config.manifest) {
|
|
2339
2535
|
ctx.state.extensionInfo = {
|
|
2340
2536
|
publicKey: ctx.config.manifest.publicKey,
|
|
2341
2537
|
name: ctx.config.manifest.name,
|
|
2342
2538
|
version: ctx.config.manifest.version,
|
|
2343
|
-
displayName: ctx.config.manifest.name
|
|
2539
|
+
displayName: ctx.config.manifest.displayName ?? ctx.config.manifest.name
|
|
2344
2540
|
};
|
|
2345
2541
|
log("Extension info loaded from manifest:", ctx.state.extensionInfo);
|
|
2346
2542
|
}
|
|
@@ -2348,7 +2544,42 @@ async function initIframeMode(ctx, log, messageHandler, request) {
|
|
|
2348
2544
|
const context = await request(EXTENSION_COMMANDS.getContext);
|
|
2349
2545
|
ctx.state.context = context;
|
|
2350
2546
|
log("Application context received:", context);
|
|
2351
|
-
return { context };
|
|
2547
|
+
return { context, port };
|
|
2548
|
+
}
|
|
2549
|
+
function waitForHostPortAsync(log) {
|
|
2550
|
+
return new Promise((resolve, reject) => {
|
|
2551
|
+
let settled = false;
|
|
2552
|
+
const cleanup = () => {
|
|
2553
|
+
window.removeEventListener("message", handler);
|
|
2554
|
+
};
|
|
2555
|
+
const timeoutId = setTimeout(() => {
|
|
2556
|
+
if (settled) return;
|
|
2557
|
+
settled = true;
|
|
2558
|
+
cleanup();
|
|
2559
|
+
reject(
|
|
2560
|
+
new HaexVaultSdkError(
|
|
2561
|
+
"TIMEOUT" /* TIMEOUT */,
|
|
2562
|
+
"errors.port_handshake_timeout",
|
|
2563
|
+
{ timeout: PORT_HANDSHAKE_TIMEOUT_MS }
|
|
2564
|
+
)
|
|
2565
|
+
);
|
|
2566
|
+
}, PORT_HANDSHAKE_TIMEOUT_MS);
|
|
2567
|
+
const handler = (event) => {
|
|
2568
|
+
const type = event.data?.type;
|
|
2569
|
+
if (type !== HAEXSPACE_MESSAGE_TYPES.PORT_INIT) return;
|
|
2570
|
+
const port = event.ports[0];
|
|
2571
|
+
if (!port) {
|
|
2572
|
+
log("PORT_INIT received but event.ports is empty \u2014 ignoring");
|
|
2573
|
+
return;
|
|
2574
|
+
}
|
|
2575
|
+
if (settled) return;
|
|
2576
|
+
settled = true;
|
|
2577
|
+
clearTimeout(timeoutId);
|
|
2578
|
+
cleanup();
|
|
2579
|
+
resolve(port);
|
|
2580
|
+
};
|
|
2581
|
+
window.addEventListener("message", handler);
|
|
2582
|
+
});
|
|
2352
2583
|
}
|
|
2353
2584
|
function sendDebugInfo(config) {
|
|
2354
2585
|
if (!config.debug) return;
|
|
@@ -2372,7 +2603,15 @@ postMessage error: ${e}`);
|
|
|
2372
2603
|
function generateRequestId(counter) {
|
|
2373
2604
|
return `req_${counter}`;
|
|
2374
2605
|
}
|
|
2375
|
-
function sendPostMessage(method, params, requestId, config, extensionInfo, pendingRequests) {
|
|
2606
|
+
function sendPostMessage(method, params, requestId, config, extensionInfo, pendingRequests, port) {
|
|
2607
|
+
if (!port) {
|
|
2608
|
+
return Promise.reject(
|
|
2609
|
+
new HaexVaultSdkError(
|
|
2610
|
+
"EXTENSION_NOT_INITIALIZED" /* EXTENSION_NOT_INITIALIZED */,
|
|
2611
|
+
"errors.port_not_connected"
|
|
2612
|
+
)
|
|
2613
|
+
);
|
|
2614
|
+
}
|
|
2376
2615
|
const request = {
|
|
2377
2616
|
method,
|
|
2378
2617
|
params,
|
|
@@ -2388,17 +2627,16 @@ function sendPostMessage(method, params, requestId, config, extensionInfo, pendi
|
|
|
2388
2627
|
);
|
|
2389
2628
|
}, config.timeout);
|
|
2390
2629
|
pendingRequests.set(requestId, { resolve, reject, timeout });
|
|
2391
|
-
const targetOrigin = "*";
|
|
2392
2630
|
if (config.debug) {
|
|
2393
2631
|
console.log("[SDK Debug] ========== Sending Request ==========");
|
|
2394
2632
|
console.log("[SDK Debug] Request ID:", requestId);
|
|
2395
2633
|
console.log("[SDK Debug] Method:", request.method);
|
|
2396
2634
|
console.log("[SDK Debug] Params:", request.params);
|
|
2397
|
-
console.log("[SDK Debug]
|
|
2635
|
+
console.log("[SDK Debug] Transport: MessagePort");
|
|
2398
2636
|
console.log("[SDK Debug] Extension info:", extensionInfo);
|
|
2399
2637
|
console.log("[SDK Debug] ========================================");
|
|
2400
2638
|
}
|
|
2401
|
-
|
|
2639
|
+
port.postMessage({ id: requestId, ...request });
|
|
2402
2640
|
});
|
|
2403
2641
|
}
|
|
2404
2642
|
async function sendInvoke(method, params, config, _log) {
|
|
@@ -2417,11 +2655,6 @@ function createMessageHandler(config, pendingRequests, extensionInfo, onEvent) {
|
|
|
2417
2655
|
return (event) => {
|
|
2418
2656
|
if (config.debug) {
|
|
2419
2657
|
console.log("[SDK Debug] ========== Message Received ==========");
|
|
2420
|
-
console.log("[SDK Debug] Event origin:", event.origin);
|
|
2421
|
-
console.log(
|
|
2422
|
-
"[SDK Debug] Event source:",
|
|
2423
|
-
event.source === window.parent ? "parent window" : "unknown"
|
|
2424
|
-
);
|
|
2425
2658
|
console.log("[SDK Debug] Event data:", event.data);
|
|
2426
2659
|
console.log("[SDK Debug] Extension info loaded:", !!extensionInfo());
|
|
2427
2660
|
console.log(
|
|
@@ -2429,12 +2662,6 @@ function createMessageHandler(config, pendingRequests, extensionInfo, onEvent) {
|
|
|
2429
2662
|
pendingRequests.size
|
|
2430
2663
|
);
|
|
2431
2664
|
}
|
|
2432
|
-
if (event.source !== window.parent) {
|
|
2433
|
-
if (config.debug) {
|
|
2434
|
-
console.error("[SDK Debug] \u274C REJECTED: Message not from parent window!");
|
|
2435
|
-
}
|
|
2436
|
-
return;
|
|
2437
|
-
}
|
|
2438
2665
|
const data = event.data;
|
|
2439
2666
|
if ("id" in data && pendingRequests.has(data.id)) {
|
|
2440
2667
|
if (config.debug) {
|
|
@@ -2500,11 +2727,10 @@ function processEvent(event, log, eventListeners, onContextChanged, onExternalRe
|
|
|
2500
2727
|
emitEvent(event, log, eventListeners);
|
|
2501
2728
|
}
|
|
2502
2729
|
function emitEvent(event, log, eventListeners) {
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
log("Event received:", event);
|
|
2730
|
+
log("emitEvent called with:", event.type, event);
|
|
2731
|
+
log("Registered event types:", Array.from(eventListeners.keys()));
|
|
2506
2732
|
const listeners = eventListeners.get(event.type);
|
|
2507
|
-
|
|
2733
|
+
log("Listeners for", event.type, ":", listeners?.size ?? 0);
|
|
2508
2734
|
if (listeners) {
|
|
2509
2735
|
listeners.forEach((callback) => callback(event));
|
|
2510
2736
|
}
|
|
@@ -2601,9 +2827,9 @@ function registerExternalHandler(action, handler, handlers, log) {
|
|
|
2601
2827
|
};
|
|
2602
2828
|
}
|
|
2603
2829
|
async function handleExternalRequest(request, handlers, respond, log) {
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2830
|
+
log("handleExternalRequest called");
|
|
2831
|
+
log("Request:", request);
|
|
2832
|
+
log("Available handlers:", Array.from(handlers.keys()));
|
|
2607
2833
|
log(`[ExternalRequest] Received request: ${request.action} from ${request.publicKey.substring(0, 20)}...`);
|
|
2608
2834
|
const handler = handlers.get(request.action);
|
|
2609
2835
|
if (!handler) {
|
|
@@ -2629,7 +2855,6 @@ async function handleExternalRequest(request, handlers, respond, log) {
|
|
|
2629
2855
|
}
|
|
2630
2856
|
}
|
|
2631
2857
|
async function respondToExternalRequest(response, request) {
|
|
2632
|
-
console.log("[SDK Debug] respondToExternalRequest called with:", JSON.stringify(response, null, 2));
|
|
2633
2858
|
await request(EXTERNAL_BRIDGE_COMMANDS.respond, response);
|
|
2634
2859
|
}
|
|
2635
2860
|
|
|
@@ -2656,6 +2881,13 @@ var HaexVaultSdk = class {
|
|
|
2656
2881
|
this.reactiveSubscribers = /* @__PURE__ */ new Set();
|
|
2657
2882
|
// Handlers
|
|
2658
2883
|
this.messageHandler = null;
|
|
2884
|
+
/**
|
|
2885
|
+
* MessagePort obtained from the main window during iframe-mode handshake.
|
|
2886
|
+
* `null` until `initIframe()` completes successfully. Every outbound
|
|
2887
|
+
* request in iframe mode flows through this port; `sendPostMessage` rejects
|
|
2888
|
+
* if called before the handshake finishes.
|
|
2889
|
+
*/
|
|
2890
|
+
this.hostPort = null;
|
|
2659
2891
|
this.setupPromise = null;
|
|
2660
2892
|
this.setupHook = null;
|
|
2661
2893
|
// Public APIs
|
|
@@ -2680,11 +2912,17 @@ var HaexVaultSdk = class {
|
|
|
2680
2912
|
this.localsend = new LocalSendAPI(this);
|
|
2681
2913
|
this.spaces = new SpacesAPI(this);
|
|
2682
2914
|
this.shell = new ShellAPI(this);
|
|
2915
|
+
this.passwords = new PasswordsAPI(this);
|
|
2916
|
+
this.mail = new MailAPI(this);
|
|
2683
2917
|
installConsoleForwarding(this.config.debug);
|
|
2684
|
-
this.readyPromise = new Promise((resolve) => {
|
|
2918
|
+
this.readyPromise = new Promise((resolve, reject) => {
|
|
2685
2919
|
this.resolveReady = resolve;
|
|
2920
|
+
this.rejectReady = reject;
|
|
2921
|
+
});
|
|
2922
|
+
this.init().catch((error) => {
|
|
2923
|
+
this.log("Init failed:", error);
|
|
2924
|
+
this.rejectReady(error);
|
|
2686
2925
|
});
|
|
2687
|
-
this.init();
|
|
2688
2926
|
}
|
|
2689
2927
|
// ==========================================================================
|
|
2690
2928
|
// Lifecycle
|
|
@@ -2712,9 +2950,14 @@ var HaexVaultSdk = class {
|
|
|
2712
2950
|
return this.setupPromise;
|
|
2713
2951
|
}
|
|
2714
2952
|
destroy() {
|
|
2715
|
-
if (this.messageHandler) {
|
|
2716
|
-
|
|
2953
|
+
if (this.messageHandler && this.hostPort) {
|
|
2954
|
+
this.hostPort.removeEventListener("message", this.messageHandler);
|
|
2717
2955
|
}
|
|
2956
|
+
if (this.hostPort) {
|
|
2957
|
+
this.hostPort.close();
|
|
2958
|
+
this.hostPort = null;
|
|
2959
|
+
}
|
|
2960
|
+
this.messageHandler = null;
|
|
2718
2961
|
this.pendingRequests.forEach(({ timeout }) => clearTimeout(timeout));
|
|
2719
2962
|
this.pendingRequests.clear();
|
|
2720
2963
|
this.eventListeners.clear();
|
|
@@ -2829,7 +3072,15 @@ var HaexVaultSdk = class {
|
|
|
2829
3072
|
return sendInvoke(method, paramsWithCredentials, this.config, this.log.bind(this));
|
|
2830
3073
|
}
|
|
2831
3074
|
const requestId = generateRequestId(++this.requestCounter);
|
|
2832
|
-
return sendPostMessage(
|
|
3075
|
+
return sendPostMessage(
|
|
3076
|
+
method,
|
|
3077
|
+
resolvedParams,
|
|
3078
|
+
requestId,
|
|
3079
|
+
this.config,
|
|
3080
|
+
this._extensionInfo,
|
|
3081
|
+
this.pendingRequests,
|
|
3082
|
+
this.hostPort
|
|
3083
|
+
);
|
|
2833
3084
|
}
|
|
2834
3085
|
// ==========================================================================
|
|
2835
3086
|
// Private: Initialization
|
|
@@ -2896,7 +3147,7 @@ var HaexVaultSdk = class {
|
|
|
2896
3147
|
() => this._extensionInfo,
|
|
2897
3148
|
this.handleEvent.bind(this)
|
|
2898
3149
|
);
|
|
2899
|
-
const { context } = await initIframeMode(
|
|
3150
|
+
const { context, port } = await initIframeMode(
|
|
2900
3151
|
{
|
|
2901
3152
|
config: this.config,
|
|
2902
3153
|
state: {
|
|
@@ -2928,12 +3179,13 @@ var HaexVaultSdk = class {
|
|
|
2928
3179
|
this.messageHandler,
|
|
2929
3180
|
this.request.bind(this)
|
|
2930
3181
|
);
|
|
3182
|
+
this.hostPort = port;
|
|
2931
3183
|
if (this.config.manifest) {
|
|
2932
3184
|
this._extensionInfo = {
|
|
2933
3185
|
publicKey: this.config.manifest.publicKey,
|
|
2934
3186
|
name: this.config.manifest.name,
|
|
2935
3187
|
version: this.config.manifest.version,
|
|
2936
|
-
displayName: this.config.manifest.name
|
|
3188
|
+
displayName: this.config.manifest.displayName ?? this.config.manifest.name
|
|
2937
3189
|
};
|
|
2938
3190
|
this.notifySubscribersInternal();
|
|
2939
3191
|
}
|
|
@@ -3603,6 +3855,10 @@ exports.HaexVaultSdkError = HaexVaultSdkError;
|
|
|
3603
3855
|
exports.KnownPath = KnownPath;
|
|
3604
3856
|
exports.LOCALSEND_EVENTS = LOCALSEND_EVENTS;
|
|
3605
3857
|
exports.LocalSendAPI = LocalSendAPI;
|
|
3858
|
+
exports.MAIL_COMMANDS = MAIL_COMMANDS;
|
|
3859
|
+
exports.MailAPI = MailAPI;
|
|
3860
|
+
exports.PASSWORD_COMMANDS = PASSWORD_COMMANDS;
|
|
3861
|
+
exports.PasswordsAPI = PasswordsAPI;
|
|
3606
3862
|
exports.PermissionErrorCode = PermissionErrorCode;
|
|
3607
3863
|
exports.PermissionStatus = PermissionStatus;
|
|
3608
3864
|
exports.PermissionsAPI = PermissionsAPI;
|