@rei-standard/amsg-server 2.6.0-next.1 → 2.6.0-next.2
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/{chunk-S5DV7AUH.cjs → chunk-GN5QTMCL.cjs} +130 -86
- package/dist/{chunk-6WA3XDPP.mjs → chunk-PVNLB6TF.mjs} +126 -82
- package/dist/{cloudflare-5Ryuxz10.d.cts → cloudflare-B-E51VjP.d.cts} +187 -114
- package/dist/{cloudflare-5Ryuxz10.d.ts → cloudflare-B-E51VjP.d.ts} +187 -114
- package/dist/cloudflare.cjs +2 -2
- package/dist/cloudflare.d.cts +1 -2
- package/dist/cloudflare.d.ts +1 -2
- package/dist/cloudflare.mjs +1 -1
- package/dist/index.cjs +11 -11
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
|
@@ -162,53 +162,127 @@ function validateScheduleMessagePayload(payload) {
|
|
|
162
162
|
return { valid: true };
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
// src/server/lib/webcrypto-utils.js
|
|
166
|
+
|
|
167
|
+
var TEXT_ENCODER = new TextEncoder();
|
|
168
|
+
var TEXT_DECODER = new TextDecoder("utf-8", { fatal: false });
|
|
169
|
+
function utf8(str) {
|
|
170
|
+
return TEXT_ENCODER.encode(String(str));
|
|
171
|
+
}
|
|
172
|
+
function utf8Decode(buf) {
|
|
173
|
+
return TEXT_DECODER.decode(_amsgshared.toUint8.call(void 0, buf));
|
|
174
|
+
}
|
|
175
|
+
function bytesToBase64(buf) {
|
|
176
|
+
const bytes = _amsgshared.toUint8.call(void 0, buf);
|
|
177
|
+
let bin = "";
|
|
178
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
179
|
+
bin += String.fromCharCode(bytes[i]);
|
|
180
|
+
}
|
|
181
|
+
return typeof btoa === "function" ? btoa(bin) : Buffer.from(bin, "binary").toString("base64");
|
|
182
|
+
}
|
|
183
|
+
function bytesToBase64Url(buf) {
|
|
184
|
+
return bytesToBase64(buf).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
185
|
+
}
|
|
186
|
+
function bytesToHex(buf) {
|
|
187
|
+
const bytes = _amsgshared.toUint8.call(void 0, buf);
|
|
188
|
+
let out = "";
|
|
189
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
190
|
+
out += bytes[i].toString(16).padStart(2, "0");
|
|
191
|
+
}
|
|
192
|
+
return out;
|
|
193
|
+
}
|
|
194
|
+
function hexToBytes(hex) {
|
|
195
|
+
const out = new Uint8Array(hex.length / 2);
|
|
196
|
+
for (let i = 0; i < out.length; i++) {
|
|
197
|
+
out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
198
|
+
}
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
function jsonToBase64Url(value) {
|
|
202
|
+
return bytesToBase64Url(utf8(JSON.stringify(value)));
|
|
203
|
+
}
|
|
204
|
+
function randomUUID() {
|
|
205
|
+
return globalThis.crypto.randomUUID();
|
|
206
|
+
}
|
|
207
|
+
function randomBytes(n) {
|
|
208
|
+
const out = new Uint8Array(n);
|
|
209
|
+
globalThis.crypto.getRandomValues(out);
|
|
210
|
+
return out;
|
|
211
|
+
}
|
|
212
|
+
|
|
165
213
|
// src/server/lib/encryption.js
|
|
166
|
-
var
|
|
167
|
-
|
|
168
|
-
|
|
214
|
+
var base64ToBytes = _amsgshared.base64UrlToBytes;
|
|
215
|
+
var TAG_LENGTH_BYTES = 16;
|
|
216
|
+
function importAesKey(hexKey, usage) {
|
|
217
|
+
return globalThis.crypto.subtle.importKey(
|
|
218
|
+
"raw",
|
|
219
|
+
hexToBytes(hexKey),
|
|
220
|
+
{ name: "AES-GCM" },
|
|
221
|
+
false,
|
|
222
|
+
[usage]
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
async function aesGcmSeal(hexKey, iv, plaintextBytes) {
|
|
226
|
+
const key = await importAesKey(hexKey, "encrypt");
|
|
227
|
+
const sealed = new Uint8Array(await globalThis.crypto.subtle.encrypt(
|
|
228
|
+
{ name: "AES-GCM", iv, tagLength: TAG_LENGTH_BYTES * 8 },
|
|
229
|
+
key,
|
|
230
|
+
plaintextBytes
|
|
231
|
+
));
|
|
232
|
+
return {
|
|
233
|
+
ciphertext: sealed.slice(0, sealed.length - TAG_LENGTH_BYTES),
|
|
234
|
+
authTag: sealed.slice(sealed.length - TAG_LENGTH_BYTES)
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
async function aesGcmOpen(hexKey, iv, ciphertext, authTag) {
|
|
238
|
+
const key = await importAesKey(hexKey, "decrypt");
|
|
239
|
+
const tagBits = authTag.length * 8;
|
|
240
|
+
const tagLength = tagBits >= 96 && tagBits <= 128 ? tagBits : 128;
|
|
241
|
+
const plain = await globalThis.crypto.subtle.decrypt(
|
|
242
|
+
{ name: "AES-GCM", iv, tagLength },
|
|
243
|
+
key,
|
|
244
|
+
_amsgshared.concatBytes.call(void 0, ciphertext, authTag)
|
|
245
|
+
);
|
|
246
|
+
return new Uint8Array(plain);
|
|
247
|
+
}
|
|
248
|
+
async function deriveUserEncryptionKey(userId, masterKey) {
|
|
249
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", utf8(masterKey + userId));
|
|
250
|
+
return bytesToHex(new Uint8Array(digest)).slice(0, 64);
|
|
169
251
|
}
|
|
170
|
-
function decryptPayload(encryptedPayload, encryptionKey) {
|
|
252
|
+
async function decryptPayload(encryptedPayload, encryptionKey) {
|
|
171
253
|
const { iv, authTag, encryptedData } = encryptedPayload;
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
254
|
+
const plain = await aesGcmOpen(
|
|
255
|
+
encryptionKey,
|
|
256
|
+
base64ToBytes(iv),
|
|
257
|
+
base64ToBytes(encryptedData),
|
|
258
|
+
base64ToBytes(authTag)
|
|
176
259
|
);
|
|
177
|
-
|
|
178
|
-
const decrypted = Buffer.concat([
|
|
179
|
-
decipher.update(Buffer.from(encryptedData, "base64")),
|
|
180
|
-
decipher.final()
|
|
181
|
-
]);
|
|
182
|
-
return JSON.parse(decrypted.toString("utf8"));
|
|
260
|
+
return JSON.parse(utf8Decode(plain));
|
|
183
261
|
}
|
|
184
|
-
function encryptPayload(payload, encryptionKey) {
|
|
262
|
+
async function encryptPayload(payload, encryptionKey) {
|
|
185
263
|
const plaintext = typeof payload === "string" ? payload : JSON.stringify(payload);
|
|
186
|
-
const iv =
|
|
187
|
-
const
|
|
188
|
-
const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
189
|
-
const authTag = cipher.getAuthTag();
|
|
264
|
+
const iv = randomBytes(12);
|
|
265
|
+
const { ciphertext, authTag } = await aesGcmSeal(encryptionKey, iv, utf8(plaintext));
|
|
190
266
|
return {
|
|
191
|
-
iv: iv
|
|
192
|
-
authTag: authTag
|
|
193
|
-
encryptedData:
|
|
267
|
+
iv: bytesToBase64(iv),
|
|
268
|
+
authTag: bytesToBase64(authTag),
|
|
269
|
+
encryptedData: bytesToBase64(ciphertext)
|
|
194
270
|
};
|
|
195
271
|
}
|
|
196
|
-
function encryptForStorage(text, encryptionKey) {
|
|
197
|
-
const iv =
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
const authTag = cipher.getAuthTag();
|
|
201
|
-
return `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted}`;
|
|
272
|
+
async function encryptForStorage(text, encryptionKey) {
|
|
273
|
+
const iv = randomBytes(16);
|
|
274
|
+
const { ciphertext, authTag } = await aesGcmSeal(encryptionKey, iv, utf8(text));
|
|
275
|
+
return `${bytesToHex(iv)}:${bytesToHex(authTag)}:${bytesToHex(ciphertext)}`;
|
|
202
276
|
}
|
|
203
|
-
function decryptFromStorage(encryptedText, encryptionKey) {
|
|
277
|
+
async function decryptFromStorage(encryptedText, encryptionKey) {
|
|
204
278
|
const [ivHex, authTagHex, encryptedDataHex] = encryptedText.split(":");
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
279
|
+
const plain = await aesGcmOpen(
|
|
280
|
+
encryptionKey,
|
|
281
|
+
hexToBytes(ivHex),
|
|
282
|
+
hexToBytes(encryptedDataHex),
|
|
283
|
+
hexToBytes(authTagHex)
|
|
209
284
|
);
|
|
210
|
-
|
|
211
|
-
return decipher.update(encryptedDataHex, "hex", "utf8") + decipher.final("utf8");
|
|
285
|
+
return utf8Decode(plain);
|
|
212
286
|
}
|
|
213
287
|
|
|
214
288
|
// src/server/lib/request.js
|
|
@@ -300,7 +374,7 @@ function createGetUserKeyHandler(ctx) {
|
|
|
300
374
|
body: {
|
|
301
375
|
success: true,
|
|
302
376
|
data: {
|
|
303
|
-
userKey: deriveUserEncryptionKey(userId, masterKey),
|
|
377
|
+
userKey: await deriveUserEncryptionKey(userId, masterKey),
|
|
304
378
|
version: 1
|
|
305
379
|
}
|
|
306
380
|
}
|
|
@@ -309,9 +383,6 @@ function createGetUserKeyHandler(ctx) {
|
|
|
309
383
|
return { GET };
|
|
310
384
|
}
|
|
311
385
|
|
|
312
|
-
// src/server/handlers/schedule-message.js
|
|
313
|
-
|
|
314
|
-
|
|
315
386
|
// src/server/lib/db-errors.js
|
|
316
387
|
function isUniqueViolation(error) {
|
|
317
388
|
if (!error || typeof error !== "object") return false;
|
|
@@ -328,7 +399,6 @@ function isUniqueViolation(error) {
|
|
|
328
399
|
|
|
329
400
|
|
|
330
401
|
|
|
331
|
-
|
|
332
402
|
var DEFAULT_SPLIT_REGEX = /([。!?!?]+)/;
|
|
333
403
|
var SLEEP_BETWEEN_MESSAGES_MS = 1500;
|
|
334
404
|
function splitOnceByRegex(chunk, regex) {
|
|
@@ -356,8 +426,8 @@ async function processSingleMessage(task, ctx, providedMasterKey) {
|
|
|
356
426
|
if (!masterKey) {
|
|
357
427
|
return { success: false, messagesSent: 0, error: "TENANT_MASTER_KEY_MISSING" };
|
|
358
428
|
}
|
|
359
|
-
const userKey = deriveUserEncryptionKey(task.user_id, masterKey);
|
|
360
|
-
const decryptedPayload = JSON.parse(decryptFromStorage(task.encrypted_payload, userKey));
|
|
429
|
+
const userKey = await deriveUserEncryptionKey(task.user_id, masterKey);
|
|
430
|
+
const decryptedPayload = JSON.parse(await decryptFromStorage(task.encrypted_payload, userKey));
|
|
361
431
|
let messageContent;
|
|
362
432
|
let llmResponse = null;
|
|
363
433
|
if (decryptedPayload.messageType === "fixed") {
|
|
@@ -389,12 +459,12 @@ async function processSingleMessage(task, ctx, providedMasterKey) {
|
|
|
389
459
|
throw new Error("VAPID configuration missing - push notifications cannot be sent");
|
|
390
460
|
}
|
|
391
461
|
const pushSubscription = decryptedPayload.pushSubscription;
|
|
392
|
-
const sessionId = task.id != null ? `sess_task_${task.id}` : `sess_${
|
|
462
|
+
const sessionId = task.id != null ? `sess_task_${task.id}` : `sess_${randomUUID()}`;
|
|
393
463
|
const source = decryptedPayload.messageType === "instant" ? "instant" : "scheduled";
|
|
394
464
|
const messageSubtype = decryptedPayload.messageSubtype || "chat";
|
|
395
465
|
const avatarUrl = decryptedPayload.avatarUrl || null;
|
|
396
466
|
const metadata = decryptedPayload.metadata || {};
|
|
397
|
-
const messageIdBase = task.id != null ? `msg_task_${task.id}` : `msg_${
|
|
467
|
+
const messageIdBase = task.id != null ? `msg_task_${task.id}` : `msg_${randomUUID()}_instant`;
|
|
398
468
|
if (reasoning) {
|
|
399
469
|
const reasoningPush = _amsgshared.buildReasoningPush.call(void 0, {
|
|
400
470
|
messageType: decryptedPayload.messageType,
|
|
@@ -606,10 +676,10 @@ function createScheduleMessageHandler(ctx) {
|
|
|
606
676
|
return { status: 400, body: { success: false, error: parsedBody.error } };
|
|
607
677
|
}
|
|
608
678
|
const encryptedBody = parsedBody.data;
|
|
679
|
+
const userKey = await deriveUserEncryptionKey(userId, masterKey);
|
|
609
680
|
let payload;
|
|
610
681
|
try {
|
|
611
|
-
|
|
612
|
-
payload = decryptPayload(encryptedBody, userKey2);
|
|
682
|
+
payload = await decryptPayload(encryptedBody, userKey);
|
|
613
683
|
} catch (error) {
|
|
614
684
|
if (error instanceof SyntaxError) {
|
|
615
685
|
return { status: 400, body: { success: false, error: { code: "INVALID_PAYLOAD_FORMAT", message: "\u89E3\u5BC6\u540E\u7684\u6570\u636E\u4E0D\u662F\u6709\u6548 JSON" } } };
|
|
@@ -627,8 +697,7 @@ function createScheduleMessageHandler(ctx) {
|
|
|
627
697
|
if (!validationResult.valid) {
|
|
628
698
|
return { status: 400, body: { success: false, error: { code: validationResult.errorCode, message: validationResult.errorMessage, details: validationResult.details } } };
|
|
629
699
|
}
|
|
630
|
-
const taskUuid = payload.uuid ||
|
|
631
|
-
const userKey = deriveUserEncryptionKey(userId, masterKey);
|
|
700
|
+
const taskUuid = payload.uuid || randomUUID();
|
|
632
701
|
const fullTaskData = {
|
|
633
702
|
contactName: payload.contactName,
|
|
634
703
|
avatarUrl: payload.avatarUrl || null,
|
|
@@ -654,7 +723,7 @@ function createScheduleMessageHandler(ctx) {
|
|
|
654
723
|
pushSubscription: payload.pushSubscription,
|
|
655
724
|
metadata: payload.metadata || {}
|
|
656
725
|
};
|
|
657
|
-
const encryptedPayload = encryptForStorage(JSON.stringify(fullTaskData), userKey);
|
|
726
|
+
const encryptedPayload = await encryptForStorage(JSON.stringify(fullTaskData), userKey);
|
|
658
727
|
if (payload.messageType === "instant") {
|
|
659
728
|
if (!ctx.vapid.email || !ctx.vapid.publicKey || !ctx.vapid.privateKey) {
|
|
660
729
|
return {
|
|
@@ -808,8 +877,8 @@ async function runScheduledTick(ctx) {
|
|
|
808
877
|
return;
|
|
809
878
|
}
|
|
810
879
|
try {
|
|
811
|
-
const userKey = deriveUserEncryptionKey(task.user_id, masterKey);
|
|
812
|
-
const decryptedPayload = JSON.parse(decryptFromStorage(task.encrypted_payload, userKey));
|
|
880
|
+
const userKey = await deriveUserEncryptionKey(task.user_id, masterKey);
|
|
881
|
+
const decryptedPayload = JSON.parse(await decryptFromStorage(task.encrypted_payload, userKey));
|
|
813
882
|
if (decryptedPayload.recurrenceType === "none") {
|
|
814
883
|
await db.deleteTaskById(task.id);
|
|
815
884
|
results.deletedOnceOffTasks++;
|
|
@@ -896,10 +965,10 @@ function createUpdateMessageHandler(ctx) {
|
|
|
896
965
|
return { status: 400, body: { success: false, error: parsedBody.error } };
|
|
897
966
|
}
|
|
898
967
|
const encryptedBody = parsedBody.data;
|
|
899
|
-
const userKey = deriveUserEncryptionKey(userId, masterKey);
|
|
968
|
+
const userKey = await deriveUserEncryptionKey(userId, masterKey);
|
|
900
969
|
let updates;
|
|
901
970
|
try {
|
|
902
|
-
updates = decryptPayload(encryptedBody, userKey);
|
|
971
|
+
updates = await decryptPayload(encryptedBody, userKey);
|
|
903
972
|
} catch (_error) {
|
|
904
973
|
return { status: 400, body: { success: false, error: { code: "DECRYPTION_FAILED", message: "\u8BF7\u6C42\u4F53\u89E3\u5BC6\u5931\u8D25" } } };
|
|
905
974
|
}
|
|
@@ -948,7 +1017,7 @@ function createUpdateMessageHandler(ctx) {
|
|
|
948
1017
|
}
|
|
949
1018
|
return { status: 409, body: { success: false, error: { code: "TASK_ALREADY_COMPLETED", message: "\u4EFB\u52A1\u5DF2\u5B8C\u6210\u6216\u5DF2\u5931\u8D25\uFF0C\u65E0\u6CD5\u66F4\u65B0" } } };
|
|
950
1019
|
}
|
|
951
|
-
const existingData = JSON.parse(decryptFromStorage(existingTask.encrypted_payload, userKey));
|
|
1020
|
+
const existingData = JSON.parse(await decryptFromStorage(existingTask.encrypted_payload, userKey));
|
|
952
1021
|
const promptUpdates = {};
|
|
953
1022
|
if (updates.completePrompt) {
|
|
954
1023
|
promptUpdates.completePrompt = updates.completePrompt;
|
|
@@ -971,7 +1040,7 @@ function createUpdateMessageHandler(ctx) {
|
|
|
971
1040
|
// string fields above are.
|
|
972
1041
|
...Object.prototype.hasOwnProperty.call(updates, "splitPattern") && { splitPattern: _nullishCoalesce(updates.splitPattern, () => ( null)) }
|
|
973
1042
|
};
|
|
974
|
-
const encryptedPayload = encryptForStorage(JSON.stringify(updatedData), userKey);
|
|
1043
|
+
const encryptedPayload = await encryptForStorage(JSON.stringify(updatedData), userKey);
|
|
975
1044
|
const extraFields = updates.nextSendAt ? { next_send_at: updates.nextSendAt } : void 0;
|
|
976
1045
|
const result = await db.updateTaskByUuid(taskUuid, userId, encryptedPayload, extraFields);
|
|
977
1046
|
if (!result) {
|
|
@@ -1064,9 +1133,9 @@ function createMessagesHandler(ctx) {
|
|
|
1064
1133
|
return { status: 400, body: { success: false, error: { code: "INVALID_PARAMETERS", message: "offset \u53C2\u6570\u65E0\u6548\uFF0C\u5FC5\u987B\u4E3A\u975E\u8D1F\u6574\u6570" } } };
|
|
1065
1134
|
}
|
|
1066
1135
|
const { tasks, total } = await db.listTasks(userId, { status, limit, offset });
|
|
1067
|
-
const userKey = deriveUserEncryptionKey(userId, masterKey);
|
|
1068
|
-
const decryptedTasks = tasks.map((task) => {
|
|
1069
|
-
const decrypted = JSON.parse(decryptFromStorage(task.encrypted_payload, userKey));
|
|
1136
|
+
const userKey = await deriveUserEncryptionKey(userId, masterKey);
|
|
1137
|
+
const decryptedTasks = await Promise.all(tasks.map(async (task) => {
|
|
1138
|
+
const decrypted = JSON.parse(await decryptFromStorage(task.encrypted_payload, userKey));
|
|
1070
1139
|
return {
|
|
1071
1140
|
id: task.id,
|
|
1072
1141
|
uuid: task.uuid,
|
|
@@ -1080,12 +1149,12 @@ function createMessagesHandler(ctx) {
|
|
|
1080
1149
|
createdAt: task.created_at,
|
|
1081
1150
|
updatedAt: task.updated_at
|
|
1082
1151
|
};
|
|
1083
|
-
});
|
|
1152
|
+
}));
|
|
1084
1153
|
const responsePayload = {
|
|
1085
1154
|
tasks: decryptedTasks,
|
|
1086
1155
|
pagination: { total, limit, offset, hasMore: offset + limit < total }
|
|
1087
1156
|
};
|
|
1088
|
-
const encryptedResponse = encryptPayload(responsePayload, userKey);
|
|
1157
|
+
const encryptedResponse = await encryptPayload(responsePayload, userKey);
|
|
1089
1158
|
return {
|
|
1090
1159
|
status: 200,
|
|
1091
1160
|
body: {
|
|
@@ -1487,31 +1556,6 @@ function createSingleUserServer(config) {
|
|
|
1487
1556
|
};
|
|
1488
1557
|
}
|
|
1489
1558
|
|
|
1490
|
-
// src/server/lib/webcrypto-utils.js
|
|
1491
|
-
|
|
1492
|
-
var TEXT_ENCODER = new TextEncoder();
|
|
1493
|
-
var TEXT_DECODER = new TextDecoder("utf-8", { fatal: false });
|
|
1494
|
-
function utf8(str) {
|
|
1495
|
-
return TEXT_ENCODER.encode(String(str));
|
|
1496
|
-
}
|
|
1497
|
-
function bytesToBase64Url(buf) {
|
|
1498
|
-
const bytes = _amsgshared.toUint8.call(void 0, buf);
|
|
1499
|
-
let bin = "";
|
|
1500
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
1501
|
-
bin += String.fromCharCode(bytes[i]);
|
|
1502
|
-
}
|
|
1503
|
-
const b64 = typeof btoa === "function" ? btoa(bin) : Buffer.from(bin, "binary").toString("base64");
|
|
1504
|
-
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
1505
|
-
}
|
|
1506
|
-
function jsonToBase64Url(value) {
|
|
1507
|
-
return bytesToBase64Url(utf8(JSON.stringify(value)));
|
|
1508
|
-
}
|
|
1509
|
-
function randomBytes2(n) {
|
|
1510
|
-
const out = new Uint8Array(n);
|
|
1511
|
-
globalThis.crypto.getRandomValues(out);
|
|
1512
|
-
return out;
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
1559
|
// src/server/lib/webpush-webcrypto.js
|
|
1516
1560
|
|
|
1517
1561
|
var KEY_INFO_PREFIX = utf8("WebPush: info\0");
|
|
@@ -1599,7 +1643,7 @@ async function encryptPushPayload({ plaintext, uaPublicKey, authSecret }) {
|
|
|
1599
1643
|
);
|
|
1600
1644
|
const keyInfo = _amsgshared.concatBytes.call(void 0, KEY_INFO_PREFIX, uaPublicKey, asPublicRaw);
|
|
1601
1645
|
const ikm = await hkdfSha256(authSecret, ecdhSecret, keyInfo, 32);
|
|
1602
|
-
const salt =
|
|
1646
|
+
const salt = randomBytes(16);
|
|
1603
1647
|
const cekBytes = await hkdfSha256(salt, ikm, CEK_INFO, 16);
|
|
1604
1648
|
const cek = await globalThis.crypto.subtle.importKey(
|
|
1605
1649
|
"raw",
|