@agentunion/fastaun-browser 0.2.17 → 0.2.18
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/auth.d.ts +3 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +293 -211
- package/dist/auth.js.map +1 -1
- package/dist/client.d.ts +11 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +1080 -812
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -1
- package/dist/config.js.map +1 -1
- package/dist/discovery.d.ts +3 -0
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +15 -1
- package/dist/discovery.js.map +1 -1
- package/dist/e2ee-group.d.ts +4 -0
- package/dist/e2ee-group.d.ts.map +1 -1
- package/dist/e2ee-group.js +327 -201
- package/dist/e2ee-group.js.map +1 -1
- package/dist/e2ee.d.ts +4 -0
- package/dist/e2ee.d.ts.map +1 -1
- package/dist/e2ee.js +176 -117
- package/dist/e2ee.js.map +1 -1
- package/dist/events.d.ts +3 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +4 -1
- package/dist/events.js.map +1 -1
- package/dist/keystore/indexeddb.d.ts +3 -0
- package/dist/keystore/indexeddb.d.ts.map +1 -1
- package/dist/keystore/indexeddb.js +153 -97
- package/dist/keystore/indexeddb.js.map +1 -1
- package/dist/logger.d.ts +37 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +112 -0
- package/dist/logger.js.map +1 -0
- package/dist/namespaces/auth.d.ts +4 -0
- package/dist/namespaces/auth.d.ts.map +1 -1
- package/dist/namespaces/auth.js +214 -101
- package/dist/namespaces/auth.js.map +1 -1
- package/dist/namespaces/custody.d.ts +3 -0
- package/dist/namespaces/custody.d.ts.map +1 -1
- package/dist/namespaces/custody.js +147 -75
- package/dist/namespaces/custody.js.map +1 -1
- package/dist/namespaces/meta.d.ts +3 -0
- package/dist/namespaces/meta.d.ts.map +1 -1
- package/dist/namespaces/meta.js +94 -43
- package/dist/namespaces/meta.js.map +1 -1
- package/dist/secret-store/indexeddb-store.d.ts +3 -0
- package/dist/secret-store/indexeddb-store.d.ts.map +1 -1
- package/dist/secret-store/indexeddb-store.js +57 -29
- package/dist/secret-store/indexeddb-store.js.map +1 -1
- package/dist/transport.d.ts +3 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +74 -4
- package/dist/transport.js.map +1 -1
- package/package.json +1 -1
package/dist/events.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { JsonValue } from './types.js';
|
|
2
|
+
import type { ModuleLogger } from './logger.js';
|
|
2
3
|
/** 事件处理函数类型 */
|
|
3
4
|
export type EventPayload = JsonValue | Error | {
|
|
4
5
|
[key: string]: JsonValue | Error;
|
|
@@ -16,6 +17,8 @@ export declare class Subscription {
|
|
|
16
17
|
}
|
|
17
18
|
/** 事件调度器:支持订阅、取消订阅、发布(同步/异步处理函数) */
|
|
18
19
|
export declare class EventDispatcher {
|
|
20
|
+
private _log;
|
|
21
|
+
setLogger(log: ModuleLogger): void;
|
|
19
22
|
private _handlers;
|
|
20
23
|
/**
|
|
21
24
|
* 订阅事件,返回订阅句柄。
|
package/dist/events.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,eAAe;AACf,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,KAAK,GACL;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE3E,iCAAiC;AACjC,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,OAAO,CAAQ;gBAEX,UAAU,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;IAM7E,WAAW;IACX,WAAW,IAAI,IAAI;CAKpB;AAED,oCAAoC;AACpC,qBAAa,eAAe;IAC1B,OAAO,CAAC,IAAI,CAA0B;IACtC,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI;IAElC,OAAO,CAAC,SAAS,CAA0C;IAE3D;;;;;;OAMG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;IAO7D,WAAW;IACX,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAWvD,4BAA4B;IACtB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CAenE"}
|
package/dist/events.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// ── 事件调度器 ──────────────────────────────────────────
|
|
2
|
+
const _noopLog = { error: () => { }, warn: () => { }, info: () => { }, debug: () => { } };
|
|
2
3
|
/** 订阅句柄,调用 unsubscribe() 取消监听 */
|
|
3
4
|
export class Subscription {
|
|
4
5
|
_dispatcher;
|
|
@@ -20,6 +21,8 @@ export class Subscription {
|
|
|
20
21
|
}
|
|
21
22
|
/** 事件调度器:支持订阅、取消订阅、发布(同步/异步处理函数) */
|
|
22
23
|
export class EventDispatcher {
|
|
24
|
+
_log = _noopLog;
|
|
25
|
+
setLogger(log) { this._log = log; }
|
|
23
26
|
_handlers = new Map();
|
|
24
27
|
/**
|
|
25
28
|
* 订阅事件,返回订阅句柄。
|
|
@@ -60,7 +63,7 @@ export class EventDispatcher {
|
|
|
60
63
|
}
|
|
61
64
|
}
|
|
62
65
|
catch (exc) {
|
|
63
|
-
|
|
66
|
+
this._log.warn(`event ${event} handler execution exception:`, exc);
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
69
|
}
|
package/dist/events.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,sDAAsD;
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ModuleLogger } from '../logger.js';
|
|
1
2
|
import type { KeyStore, GroupStateRecord } from './index.js';
|
|
2
3
|
import { type GroupSecretRecord, type IdentityRecord, type KeyPairRecord, type MetadataRecord, type PrekeyMap, type PrekeyRecord, type SessionRecord } from '../types.js';
|
|
3
4
|
/**
|
|
@@ -10,6 +11,8 @@ import { type GroupSecretRecord, type IdentityRecord, type KeyPairRecord, type M
|
|
|
10
11
|
* - 若检测到旧版本把结构化数据写进了 metadata,会自动迁移到结构化 store。
|
|
11
12
|
*/
|
|
12
13
|
export declare class IndexedDBKeyStore implements KeyStore {
|
|
14
|
+
private _log;
|
|
15
|
+
setLogger(log: ModuleLogger): void;
|
|
13
16
|
private static _aidTails;
|
|
14
17
|
/** 私钥加密种子;为空时降级为明文存储(向后兼容) */
|
|
15
18
|
private _encryptionSeed;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexeddb.d.ts","sourceRoot":"","sources":["../../src/keystore/indexeddb.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"indexeddb.d.ts","sourceRoot":"","sources":["../../src/keystore/indexeddb.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// ── IndexedDB KeyStore 实现 ──────────────────────────────
|
|
2
2
|
import { pemToArrayBuffer } from '../crypto.js';
|
|
3
3
|
import { normalizeInstanceId } from '../config.js';
|
|
4
|
+
const _noopLog = { error: () => { }, warn: () => { }, info: () => { }, debug: () => { } };
|
|
4
5
|
import { isJsonObject, } from '../types.js';
|
|
5
6
|
/** AID 安全化(替换路径分隔符) */
|
|
6
7
|
function safeAid(aid) {
|
|
@@ -393,6 +394,8 @@ async function idbDelete(storeName, key) {
|
|
|
393
394
|
* - 若检测到旧版本把结构化数据写进了 metadata,会自动迁移到结构化 store。
|
|
394
395
|
*/
|
|
395
396
|
export class IndexedDBKeyStore {
|
|
397
|
+
_log = _noopLog;
|
|
398
|
+
setLogger(log) { this._log = log; }
|
|
396
399
|
static _aidTails = new Map();
|
|
397
400
|
/** 私钥加密种子;为空时降级为明文存储(向后兼容) */
|
|
398
401
|
_encryptionSeed;
|
|
@@ -420,29 +423,39 @@ export class IndexedDBKeyStore {
|
|
|
420
423
|
}
|
|
421
424
|
}
|
|
422
425
|
async listIdentities() {
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
426
|
+
const tStart = Date.now();
|
|
427
|
+
this._log.debug('listIdentities enter');
|
|
428
|
+
try {
|
|
429
|
+
const records = await idbGetAll(STORE_METADATA);
|
|
430
|
+
const aids = new Set();
|
|
431
|
+
for (const item of records) {
|
|
432
|
+
if (item.key.startsWith('_seq_|'))
|
|
433
|
+
continue;
|
|
434
|
+
const value = item.value;
|
|
435
|
+
const aid = typeof value === 'object' && value !== null && isRecord(value) && typeof value.aid === 'string' && value.aid
|
|
436
|
+
? value.aid
|
|
437
|
+
: item.key;
|
|
438
|
+
aids.add(String(aid));
|
|
439
|
+
}
|
|
440
|
+
for (const item of await idbGetAll(STORE_KEY_PAIRS)) {
|
|
441
|
+
if (!item.key.startsWith('_seq_|'))
|
|
442
|
+
aids.add(item.key);
|
|
443
|
+
}
|
|
444
|
+
for (const item of await idbGetAll(STORE_CERTS)) {
|
|
445
|
+
if (item.key.startsWith('_seq_|'))
|
|
446
|
+
continue;
|
|
447
|
+
const [safe] = item.key.split('|', 1);
|
|
448
|
+
if (safe)
|
|
449
|
+
aids.add(safe);
|
|
450
|
+
}
|
|
451
|
+
const result = [...aids].sort();
|
|
452
|
+
this._log.debug(`listIdentities exit: elapsed=${Date.now() - tStart}ms count=${result.length}`);
|
|
453
|
+
return result;
|
|
437
454
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
const [safe] = item.key.split('|', 1);
|
|
442
|
-
if (safe)
|
|
443
|
-
aids.add(safe);
|
|
455
|
+
catch (err) {
|
|
456
|
+
this._log.debug(`listIdentities exit (error): elapsed=${Date.now() - tStart}ms err=${err instanceof Error ? err.message : String(err)}`);
|
|
457
|
+
throw err;
|
|
444
458
|
}
|
|
445
|
-
return [...aids].sort();
|
|
446
459
|
}
|
|
447
460
|
// ── 密钥对 ──────────────────────────────────────────
|
|
448
461
|
async loadKeyPair(aid) {
|
|
@@ -459,7 +472,7 @@ export class IndexedDBKeyStore {
|
|
|
459
472
|
delete result._encrypted_pk;
|
|
460
473
|
}
|
|
461
474
|
catch {
|
|
462
|
-
|
|
475
|
+
this._log.error(`[keystore] decrypt ${aid} private keyfailed, maybe encryptionSeed mismatch`);
|
|
463
476
|
}
|
|
464
477
|
}
|
|
465
478
|
else if (
|
|
@@ -485,30 +498,54 @@ export class IndexedDBKeyStore {
|
|
|
485
498
|
}
|
|
486
499
|
// ── 证书 ──────────────────────────────────────────
|
|
487
500
|
async loadCert(aid, certFingerprint) {
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
501
|
+
const tStart = Date.now();
|
|
502
|
+
this._log.debug(`loadCert enter: aid=${aid} fingerprint=${certFingerprint ?? '<none>'}`);
|
|
503
|
+
try {
|
|
504
|
+
const normalized = normalizeCertFingerprint(certFingerprint);
|
|
505
|
+
if (normalized) {
|
|
506
|
+
const versioned = await idbGet(STORE_CERTS, certStoreKey(aid, normalized));
|
|
507
|
+
if (typeof versioned === 'string') {
|
|
508
|
+
this._log.debug(`loadCert exit: elapsed=${Date.now() - tStart}ms aid=${aid} found=true source=versioned`);
|
|
509
|
+
return versioned;
|
|
510
|
+
}
|
|
511
|
+
const active = await idbGet(STORE_CERTS, certStoreKey(aid));
|
|
512
|
+
if (typeof active === 'string' && await fingerprintFromCertPem(active) === normalized) {
|
|
513
|
+
this._log.debug(`loadCert exit: elapsed=${Date.now() - tStart}ms aid=${aid} found=true source=active`);
|
|
514
|
+
return active;
|
|
515
|
+
}
|
|
516
|
+
this._log.debug(`loadCert exit: elapsed=${Date.now() - tStart}ms aid=${aid} found=false`);
|
|
517
|
+
return null;
|
|
496
518
|
}
|
|
497
|
-
|
|
519
|
+
const data = await idbGet(STORE_CERTS, certStoreKey(aid));
|
|
520
|
+
const found = typeof data === 'string';
|
|
521
|
+
this._log.debug(`loadCert exit: elapsed=${Date.now() - tStart}ms aid=${aid} found=${found}`);
|
|
522
|
+
return found ? data : null;
|
|
523
|
+
}
|
|
524
|
+
catch (err) {
|
|
525
|
+
this._log.debug(`loadCert exit (error): elapsed=${Date.now() - tStart}ms aid=${aid} err=${err instanceof Error ? err.message : String(err)}`);
|
|
526
|
+
throw err;
|
|
498
527
|
}
|
|
499
|
-
const data = await idbGet(STORE_CERTS, certStoreKey(aid));
|
|
500
|
-
return typeof data === 'string' ? data : null;
|
|
501
528
|
}
|
|
502
529
|
async saveCert(aid, certPem, certFingerprint, opts) {
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
530
|
+
const tStart = Date.now();
|
|
531
|
+
this._log.debug(`saveCert enter: aid=${aid} fingerprint=${certFingerprint ?? '<none>'} make_active=${opts?.makeActive ?? false}`);
|
|
532
|
+
try {
|
|
533
|
+
const normalized = normalizeCertFingerprint(certFingerprint);
|
|
534
|
+
if (normalized) {
|
|
535
|
+
await idbPut(STORE_CERTS, certStoreKey(aid, normalized), certPem);
|
|
536
|
+
if (opts?.makeActive) {
|
|
537
|
+
await idbPut(STORE_CERTS, certStoreKey(aid), certPem);
|
|
538
|
+
}
|
|
539
|
+
this._log.debug(`saveCert exit: elapsed=${Date.now() - tStart}ms aid=${aid}`);
|
|
540
|
+
return;
|
|
508
541
|
}
|
|
509
|
-
|
|
542
|
+
await idbPut(STORE_CERTS, certStoreKey(aid), certPem);
|
|
543
|
+
this._log.debug(`saveCert exit: elapsed=${Date.now() - tStart}ms aid=${aid}`);
|
|
544
|
+
}
|
|
545
|
+
catch (err) {
|
|
546
|
+
this._log.debug(`saveCert exit (error): elapsed=${Date.now() - tStart}ms aid=${aid} err=${err instanceof Error ? err.message : String(err)}`);
|
|
547
|
+
throw err;
|
|
510
548
|
}
|
|
511
|
-
await idbPut(STORE_CERTS, certStoreKey(aid), certPem);
|
|
512
549
|
}
|
|
513
550
|
// ── 实例态 ──────────────────────────────────────────
|
|
514
551
|
async loadInstanceState(aid, deviceId, slotId = '') {
|
|
@@ -534,71 +571,90 @@ export class IndexedDBKeyStore {
|
|
|
534
571
|
}
|
|
535
572
|
// ── 身份信息(组合操作) ──────────────────────────
|
|
536
573
|
async loadIdentity(aid) {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
if (
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
574
|
+
const tStart = Date.now();
|
|
575
|
+
this._log.debug(`loadIdentity enter: aid=${aid}`);
|
|
576
|
+
try {
|
|
577
|
+
const result = await this._withAidLock(aid, async () => {
|
|
578
|
+
const [keyPair, cert] = await Promise.all([
|
|
579
|
+
this._loadKeyPairUnlocked(aid),
|
|
580
|
+
this._loadCertUnlocked(aid),
|
|
581
|
+
]);
|
|
582
|
+
// 直接读取 metadata KV(含旧数据迁移)
|
|
583
|
+
const metadataOnly = await this._migrateLegacyStructuredStateUnlocked(aid);
|
|
584
|
+
const hasMeta = Object.keys(metadataOnly).length > 0;
|
|
585
|
+
if (!keyPair && !cert && !hasMeta)
|
|
586
|
+
return null;
|
|
587
|
+
const identity = {};
|
|
588
|
+
if (hasMeta)
|
|
589
|
+
Object.assign(identity, metadataOnly);
|
|
590
|
+
if (keyPair)
|
|
591
|
+
Object.assign(identity, keyPair);
|
|
592
|
+
if (cert) {
|
|
593
|
+
// key/cert 公钥一致性校验:防止 cert 被意外覆盖
|
|
594
|
+
const localPubB64 = keyPair?.public_key_der_b64;
|
|
595
|
+
if (typeof localPubB64 === 'string' && localPubB64) {
|
|
596
|
+
const certSpkiB64 = extractSpkiB64FromCertPem(cert);
|
|
597
|
+
if (certSpkiB64 && certSpkiB64 !== localPubB64) {
|
|
598
|
+
this._log.error(`[keystore] identity ${aid} key public key mismatches cert public key, discard cert`);
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
identity.cert = cert;
|
|
602
|
+
}
|
|
559
603
|
}
|
|
560
604
|
else {
|
|
561
605
|
identity.cert = cert;
|
|
562
606
|
}
|
|
563
607
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
608
|
+
return identity;
|
|
609
|
+
});
|
|
610
|
+
this._log.debug(`loadIdentity exit: elapsed=${Date.now() - tStart}ms aid=${aid} found=${result !== null}`);
|
|
611
|
+
return result;
|
|
612
|
+
}
|
|
613
|
+
catch (err) {
|
|
614
|
+
this._log.debug(`loadIdentity exit (error): elapsed=${Date.now() - tStart}ms aid=${aid} err=${err instanceof Error ? err.message : String(err)}`);
|
|
615
|
+
throw err;
|
|
616
|
+
}
|
|
570
617
|
}
|
|
571
618
|
async saveIdentity(aid, identity) {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
}
|
|
581
|
-
const cert = identity.cert;
|
|
582
|
-
if (typeof cert === 'string' && cert) {
|
|
583
|
-
await this._saveCertUnlocked(aid, cert);
|
|
584
|
-
}
|
|
585
|
-
const metadataFields = {};
|
|
586
|
-
for (const [key, value] of Object.entries(identity)) {
|
|
587
|
-
if (!['private_key_pem', 'public_key_der_b64', 'curve', 'cert'].includes(key)) {
|
|
588
|
-
metadataFields[key] = value;
|
|
619
|
+
const tStart = Date.now();
|
|
620
|
+
this._log.debug(`saveIdentity enter: aid=${aid} has_cert=${!!identity.cert}`);
|
|
621
|
+
try {
|
|
622
|
+
await this._withAidLock(aid, async () => {
|
|
623
|
+
const keyPairFields = {};
|
|
624
|
+
for (const key of ['private_key_pem', 'public_key_der_b64', 'curve']) {
|
|
625
|
+
if (key in identity)
|
|
626
|
+
keyPairFields[key] = identity[key];
|
|
589
627
|
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
if (Object.keys(metadataFields).length > 0) {
|
|
593
|
-
await this._replaceStructuredStateUnlocked(aid, metadataFields);
|
|
594
|
-
const plain = stripStructuredFields(metadataFields);
|
|
595
|
-
if (Object.keys(plain).length > 0) {
|
|
596
|
-
const current = await this._migrateLegacyStructuredStateUnlocked(aid);
|
|
597
|
-
Object.assign(current, plain);
|
|
598
|
-
await this._saveMetadataOnlyUnlocked(aid, current);
|
|
628
|
+
if (Object.keys(keyPairFields).length > 0) {
|
|
629
|
+
await this._saveKeyPairUnlocked(aid, keyPairFields);
|
|
599
630
|
}
|
|
600
|
-
|
|
601
|
-
|
|
631
|
+
const cert = identity.cert;
|
|
632
|
+
if (typeof cert === 'string' && cert) {
|
|
633
|
+
await this._saveCertUnlocked(aid, cert);
|
|
634
|
+
}
|
|
635
|
+
const metadataFields = {};
|
|
636
|
+
for (const [key, value] of Object.entries(identity)) {
|
|
637
|
+
if (!['private_key_pem', 'public_key_der_b64', 'curve', 'cert'].includes(key)) {
|
|
638
|
+
metadataFields[key] = value;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
// 增量保存 metadata 字段
|
|
642
|
+
if (Object.keys(metadataFields).length > 0) {
|
|
643
|
+
await this._replaceStructuredStateUnlocked(aid, metadataFields);
|
|
644
|
+
const plain = stripStructuredFields(metadataFields);
|
|
645
|
+
if (Object.keys(plain).length > 0) {
|
|
646
|
+
const current = await this._migrateLegacyStructuredStateUnlocked(aid);
|
|
647
|
+
Object.assign(current, plain);
|
|
648
|
+
await this._saveMetadataOnlyUnlocked(aid, current);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
this._log.debug(`saveIdentity exit: elapsed=${Date.now() - tStart}ms aid=${aid}`);
|
|
653
|
+
}
|
|
654
|
+
catch (err) {
|
|
655
|
+
this._log.debug(`saveIdentity exit (error): elapsed=${Date.now() - tStart}ms aid=${aid} err=${err instanceof Error ? err.message : String(err)}`);
|
|
656
|
+
throw err;
|
|
657
|
+
}
|
|
602
658
|
}
|
|
603
659
|
// ── 结构化 prekeys ───────────────────────────────────
|
|
604
660
|
async loadE2EEPrekeys(aid, deviceId) {
|
|
@@ -802,7 +858,7 @@ export class IndexedDBKeyStore {
|
|
|
802
858
|
delete result._encrypted_pk;
|
|
803
859
|
}
|
|
804
860
|
catch {
|
|
805
|
-
|
|
861
|
+
this._log.error(`[keystore] decrypt ${aid} private keyfailed, maybe encryptionSeed mismatch`);
|
|
806
862
|
}
|
|
807
863
|
}
|
|
808
864
|
else if (
|