@embarkai/ui-kit 0.2.7 → 0.3.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/iframe/index.html +1 -1
- package/dist/iframe/main.js +26 -11
- package/dist/iframe/main.js.map +1 -1
- package/dist/index.cjs +212 -124
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +121 -33
- package/dist/index.js.map +1 -1
- package/package.json +15 -14
package/dist/iframe/index.html
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
<meta http-equiv="X-Content-Type-Options" content="nosniff" />
|
|
16
16
|
<meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin" />
|
|
17
17
|
|
|
18
|
-
<title>EmbarkAI Secure Wallet - iframe version 0.
|
|
18
|
+
<title>EmbarkAI Secure Wallet - iframe version 0.3.0</title>
|
|
19
19
|
|
|
20
20
|
<!-- Styles will be injected by build process -->
|
|
21
21
|
<style>
|
package/dist/iframe/main.js
CHANGED
|
@@ -165,18 +165,23 @@ async function encryptKeyshare(data, password, encryptionMethod, credentialId) {
|
|
|
165
165
|
credentialId: encryptionMethod === "passkey" ? credentialId : void 0
|
|
166
166
|
};
|
|
167
167
|
}
|
|
168
|
+
function serializeAad(aad) {
|
|
169
|
+
return new TextEncoder().encode(JSON.stringify(aad));
|
|
170
|
+
}
|
|
168
171
|
async function envelopeEncryptKeyshare(data, userId) {
|
|
169
172
|
const { kek: kekBytes, credentialId } = await deriveKEKFromPasskey(userId);
|
|
170
173
|
console.log("[envelopeEncryptKeyshare] Using credential ID for encryption:", credentialId);
|
|
174
|
+
const aad = { userId: data.userId, version: 2, deviceId: "embarkai-ui-kit" };
|
|
175
|
+
const aadBytes = serializeAad(aad);
|
|
171
176
|
const dek = crypto.getRandomValues(new Uint8Array(32));
|
|
172
177
|
const kek = await crypto.subtle.importKey("raw", kekBytes, "AES-GCM", false, ["encrypt"]);
|
|
173
178
|
const plaintext = JSON.stringify(data);
|
|
174
179
|
const plaintextBytes = new TextEncoder().encode(plaintext);
|
|
175
180
|
const dekCryptoKey = await crypto.subtle.importKey("raw", dek, "AES-GCM", false, ["encrypt"]);
|
|
176
181
|
const dataIv = crypto.getRandomValues(new Uint8Array(12));
|
|
177
|
-
const encryptedData = await crypto.subtle.encrypt({ name: "AES-GCM", iv: dataIv }, dekCryptoKey, plaintextBytes);
|
|
182
|
+
const encryptedData = await crypto.subtle.encrypt({ name: "AES-GCM", iv: dataIv, additionalData: aadBytes }, dekCryptoKey, plaintextBytes);
|
|
178
183
|
const wrapIv = crypto.getRandomValues(new Uint8Array(12));
|
|
179
|
-
const wrappedDekData = await crypto.subtle.encrypt({ name: "AES-GCM", iv: wrapIv }, kek, dek);
|
|
184
|
+
const wrappedDekData = await crypto.subtle.encrypt({ name: "AES-GCM", iv: wrapIv, additionalData: aadBytes }, kek, dek);
|
|
180
185
|
const ciphertextWithIv = new Uint8Array(dataIv.length + encryptedData.byteLength);
|
|
181
186
|
ciphertextWithIv.set(dataIv, 0);
|
|
182
187
|
ciphertextWithIv.set(new Uint8Array(encryptedData), dataIv.length);
|
|
@@ -188,7 +193,7 @@ async function envelopeEncryptKeyshare(data, userId) {
|
|
|
188
193
|
wrapped_dek: bytesToBase64(wrappedDekWithIv),
|
|
189
194
|
kdf: { prf: "webauthn-prf", hkdf: "hkdf-sha256", info: "client-share" },
|
|
190
195
|
alg: { data: "aes-256-gcm", wrap: "aes-256-gcm" },
|
|
191
|
-
aad
|
|
196
|
+
aad,
|
|
192
197
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
193
198
|
expiresAt: null,
|
|
194
199
|
encryptionMethod: "passkey",
|
|
@@ -197,6 +202,8 @@ async function envelopeEncryptKeyshare(data, userId) {
|
|
|
197
202
|
}
|
|
198
203
|
async function envelopeEncryptKeyshareWithPassword(data, password) {
|
|
199
204
|
console.log("[envelopeEncryptKeyshareWithPassword] Encrypting with password");
|
|
205
|
+
const aad = { userId: data.userId, version: 2, deviceId: "embarkai-ui-kit" };
|
|
206
|
+
const aadBytes = serializeAad(aad);
|
|
200
207
|
const dek = crypto.getRandomValues(new Uint8Array(32));
|
|
201
208
|
const salt = crypto.getRandomValues(new Uint8Array(16));
|
|
202
209
|
const kekKey = await deriveKeyFromPassword(password, salt);
|
|
@@ -204,9 +211,9 @@ async function envelopeEncryptKeyshareWithPassword(data, password) {
|
|
|
204
211
|
const plaintextBytes = new TextEncoder().encode(plaintext);
|
|
205
212
|
const dekCryptoKey = await crypto.subtle.importKey("raw", dek, "AES-GCM", false, ["encrypt"]);
|
|
206
213
|
const dataIv = crypto.getRandomValues(new Uint8Array(12));
|
|
207
|
-
const encryptedData = await crypto.subtle.encrypt({ name: "AES-GCM", iv: dataIv }, dekCryptoKey, plaintextBytes);
|
|
214
|
+
const encryptedData = await crypto.subtle.encrypt({ name: "AES-GCM", iv: dataIv, additionalData: aadBytes }, dekCryptoKey, plaintextBytes);
|
|
208
215
|
const wrapIv = crypto.getRandomValues(new Uint8Array(12));
|
|
209
|
-
const wrappedDekData = await crypto.subtle.encrypt({ name: "AES-GCM", iv: wrapIv }, kekKey, dek);
|
|
216
|
+
const wrappedDekData = await crypto.subtle.encrypt({ name: "AES-GCM", iv: wrapIv, additionalData: aadBytes }, kekKey, dek);
|
|
210
217
|
const ciphertextWithIv = new Uint8Array(dataIv.length + encryptedData.byteLength);
|
|
211
218
|
ciphertextWithIv.set(dataIv, 0);
|
|
212
219
|
ciphertextWithIv.set(new Uint8Array(encryptedData), dataIv.length);
|
|
@@ -219,7 +226,7 @@ async function envelopeEncryptKeyshareWithPassword(data, password) {
|
|
|
219
226
|
wrapped_dek: bytesToBase64(wrappedDekWithIv),
|
|
220
227
|
kdf: { prf: "pbkdf2", hkdf: "hkdf-sha256", info: "client-share" },
|
|
221
228
|
alg: { data: "aes-256-gcm", wrap: "aes-256-gcm" },
|
|
222
|
-
aad
|
|
229
|
+
aad,
|
|
223
230
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
224
231
|
expiresAt: null,
|
|
225
232
|
encryptionMethod: "password"
|
|
@@ -233,6 +240,8 @@ async function envelopeDecryptKeyshare(envelope, userId) {
|
|
|
233
240
|
console.log("[iframe][envelopeDecryptKeyshare] KEK bytes length:", kekBytes.byteLength);
|
|
234
241
|
console.log("[iframe][envelopeDecryptKeyshare] Importing KEK as crypto key...");
|
|
235
242
|
const kek = await crypto.subtle.importKey("raw", kekBytes, "AES-GCM", false, ["decrypt"]);
|
|
243
|
+
const useAad = envelope.aad?.version >= 2;
|
|
244
|
+
const aadBytes = useAad ? serializeAad(envelope.aad) : void 0;
|
|
236
245
|
console.log("[iframe][envelopeDecryptKeyshare] Decrypting wrapped DEK...");
|
|
237
246
|
const wrappedDekWithIv = base64ToBytes(envelope.wrapped_dek);
|
|
238
247
|
console.log("[iframe][envelopeDecryptKeyshare] Wrapped DEK with IV length:", wrappedDekWithIv.length);
|
|
@@ -240,7 +249,7 @@ async function envelopeDecryptKeyshare(envelope, userId) {
|
|
|
240
249
|
const wrappedDekData = wrappedDekWithIv.slice(12);
|
|
241
250
|
console.log("[iframe][envelopeDecryptKeyshare] Wrap IV length:", wrapIv.length, "Wrapped DEK data length:", wrappedDekData.length);
|
|
242
251
|
try {
|
|
243
|
-
const dekBytes = await crypto.subtle.decrypt({ name: "AES-GCM", iv: wrapIv }, kek, wrappedDekData);
|
|
252
|
+
const dekBytes = await crypto.subtle.decrypt({ name: "AES-GCM", iv: wrapIv, ...aadBytes && { additionalData: aadBytes } }, kek, wrappedDekData);
|
|
244
253
|
console.log("[iframe][envelopeDecryptKeyshare] DEK decrypted successfully, length:", dekBytes.byteLength);
|
|
245
254
|
console.log("[iframe][envelopeDecryptKeyshare] Importing DEK as crypto key...");
|
|
246
255
|
const dekCryptoKey = await crypto.subtle.importKey("raw", dekBytes, "AES-GCM", false, ["decrypt"]);
|
|
@@ -250,7 +259,7 @@ async function envelopeDecryptKeyshare(envelope, userId) {
|
|
|
250
259
|
const dataIv = ciphertextWithIv.slice(0, 12);
|
|
251
260
|
const encryptedData = ciphertextWithIv.slice(12);
|
|
252
261
|
console.log("[iframe][envelopeDecryptKeyshare] Data IV length:", dataIv.length, "Encrypted data length:", encryptedData.length);
|
|
253
|
-
const decryptedData = await crypto.subtle.decrypt({ name: "AES-GCM", iv: dataIv }, dekCryptoKey, encryptedData);
|
|
262
|
+
const decryptedData = await crypto.subtle.decrypt({ name: "AES-GCM", iv: dataIv, ...aadBytes && { additionalData: aadBytes } }, dekCryptoKey, encryptedData);
|
|
254
263
|
console.log("[iframe][envelopeDecryptKeyshare] Main data decrypted successfully, length:", decryptedData.byteLength);
|
|
255
264
|
console.log("[iframe][envelopeDecryptKeyshare] Parsing JSON...");
|
|
256
265
|
const plaintext = new TextDecoder().decode(decryptedData);
|
|
@@ -272,16 +281,18 @@ async function envelopeDecryptKeyshareWithPassword(envelope, password) {
|
|
|
272
281
|
const salt = wrappedDekWithSaltAndIv.slice(0, 16);
|
|
273
282
|
const wrapIv = wrappedDekWithSaltAndIv.slice(16, 28);
|
|
274
283
|
const wrappedDekData = wrappedDekWithSaltAndIv.slice(28);
|
|
284
|
+
const useAad = envelope.aad?.version >= 2;
|
|
285
|
+
const aadBytes = useAad ? serializeAad(envelope.aad) : void 0;
|
|
275
286
|
console.log("[iframe][envelopeDecryptKeyshareWithPassword] Salt length:", salt.length, "Wrap IV length:", wrapIv.length, "Wrapped DEK data length:", wrappedDekData.length);
|
|
276
287
|
try {
|
|
277
288
|
const kekKey = await deriveKeyFromPassword(password, salt);
|
|
278
|
-
const dekBytes = await crypto.subtle.decrypt({ name: "AES-GCM", iv: wrapIv }, kekKey, wrappedDekData);
|
|
289
|
+
const dekBytes = await crypto.subtle.decrypt({ name: "AES-GCM", iv: wrapIv, ...aadBytes && { additionalData: aadBytes } }, kekKey, wrappedDekData);
|
|
279
290
|
console.log("[iframe][envelopeDecryptKeyshareWithPassword] DEK decrypted successfully, length:", dekBytes.byteLength);
|
|
280
291
|
const dekCryptoKey = await crypto.subtle.importKey("raw", dekBytes, "AES-GCM", false, ["decrypt"]);
|
|
281
292
|
const ciphertextWithIv = base64ToBytes(envelope.ciphertext_share);
|
|
282
293
|
const dataIv = ciphertextWithIv.slice(0, 12);
|
|
283
294
|
const encryptedData = ciphertextWithIv.slice(12);
|
|
284
|
-
const decryptedData = await crypto.subtle.decrypt({ name: "AES-GCM", iv: dataIv }, dekCryptoKey, encryptedData);
|
|
295
|
+
const decryptedData = await crypto.subtle.decrypt({ name: "AES-GCM", iv: dataIv, ...aadBytes && { additionalData: aadBytes } }, dekCryptoKey, encryptedData);
|
|
285
296
|
console.log("[iframe][envelopeDecryptKeyshareWithPassword] Main data decrypted successfully");
|
|
286
297
|
const plaintext = new TextDecoder().decode(decryptedData);
|
|
287
298
|
const result = JSON.parse(plaintext);
|
|
@@ -3314,6 +3325,10 @@ var SdkChannelManager = class {
|
|
|
3314
3325
|
* Validate channel token and origin
|
|
3315
3326
|
*/
|
|
3316
3327
|
validateChannel(channelToken, origin) {
|
|
3328
|
+
if (!channelToken) {
|
|
3329
|
+
console.warn("[iframe][SdkChannel] \u2717 channelToken is null/undefined");
|
|
3330
|
+
return false;
|
|
3331
|
+
}
|
|
3317
3332
|
const channel = this.channels.get(channelToken);
|
|
3318
3333
|
if (!channel) {
|
|
3319
3334
|
console.warn(`[iframe][SdkChannel] \u2717 NOT FOUND: ${channelToken.slice(0, 16)}... (active channels: ${this.channels.size})`);
|
|
@@ -4395,7 +4410,7 @@ var SigningManager = class extends TokenRefreshApiClient {
|
|
|
4395
4410
|
};
|
|
4396
4411
|
|
|
4397
4412
|
// src/iframe/main.ts
|
|
4398
|
-
var IFRAME_VERSION = "0.
|
|
4413
|
+
var IFRAME_VERSION = "0.3.0";
|
|
4399
4414
|
var IframeWallet = class {
|
|
4400
4415
|
constructor() {
|
|
4401
4416
|
console.log("=".repeat(60));
|