@agentunion/fastaun 0.2.13

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.
Files changed (69) hide show
  1. package/LICENSE +17 -0
  2. package/README.md +78 -0
  3. package/dist/auth.d.ts +287 -0
  4. package/dist/auth.js +1668 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/client.d.ts +359 -0
  7. package/dist/client.js +3918 -0
  8. package/dist/client.js.map +1 -0
  9. package/dist/config.d.ts +43 -0
  10. package/dist/config.js +119 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/crypto.d.ts +41 -0
  13. package/dist/crypto.js +85 -0
  14. package/dist/crypto.js.map +1 -0
  15. package/dist/discovery.d.ts +22 -0
  16. package/dist/discovery.js +110 -0
  17. package/dist/discovery.js.map +1 -0
  18. package/dist/e2ee-group.d.ts +192 -0
  19. package/dist/e2ee-group.js +1134 -0
  20. package/dist/e2ee-group.js.map +1 -0
  21. package/dist/e2ee.d.ts +120 -0
  22. package/dist/e2ee.js +890 -0
  23. package/dist/e2ee.js.map +1 -0
  24. package/dist/errors.d.ts +115 -0
  25. package/dist/errors.js +253 -0
  26. package/dist/errors.js.map +1 -0
  27. package/dist/events.d.ts +39 -0
  28. package/dist/events.js +82 -0
  29. package/dist/events.js.map +1 -0
  30. package/dist/index.d.ts +23 -0
  31. package/dist/index.js +32 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/keystore/aid-db.d.ts +79 -0
  34. package/dist/keystore/aid-db.js +621 -0
  35. package/dist/keystore/aid-db.js.map +1 -0
  36. package/dist/keystore/file.d.ts +82 -0
  37. package/dist/keystore/file.js +395 -0
  38. package/dist/keystore/file.js.map +1 -0
  39. package/dist/keystore/index.d.ts +88 -0
  40. package/dist/keystore/index.js +7 -0
  41. package/dist/keystore/index.js.map +1 -0
  42. package/dist/keystore/sqlite-backup.d.ts +40 -0
  43. package/dist/keystore/sqlite-backup.js +379 -0
  44. package/dist/keystore/sqlite-backup.js.map +1 -0
  45. package/dist/logger.d.ts +6 -0
  46. package/dist/logger.js +53 -0
  47. package/dist/logger.js.map +1 -0
  48. package/dist/namespaces/auth.d.ts +49 -0
  49. package/dist/namespaces/auth.js +248 -0
  50. package/dist/namespaces/auth.js.map +1 -0
  51. package/dist/namespaces/custody.d.ts +47 -0
  52. package/dist/namespaces/custody.js +231 -0
  53. package/dist/namespaces/custody.js.map +1 -0
  54. package/dist/secret-store/file-store.d.ts +25 -0
  55. package/dist/secret-store/file-store.js +124 -0
  56. package/dist/secret-store/file-store.js.map +1 -0
  57. package/dist/secret-store/index.d.ts +28 -0
  58. package/dist/secret-store/index.js +19 -0
  59. package/dist/secret-store/index.js.map +1 -0
  60. package/dist/seq-tracker.d.ts +29 -0
  61. package/dist/seq-tracker.js +221 -0
  62. package/dist/seq-tracker.js.map +1 -0
  63. package/dist/transport.d.ts +60 -0
  64. package/dist/transport.js +355 -0
  65. package/dist/transport.js.map +1 -0
  66. package/dist/types.d.ts +170 -0
  67. package/dist/types.js +12 -0
  68. package/dist/types.js.map +1 -0
  69. package/package.json +42 -0
@@ -0,0 +1,82 @@
1
+ /**
2
+ * 基于文件(key.json/cert.pem)+ AIDDatabase(SQLite)的 KeyStore 实现。
3
+ *
4
+ * 与 Python SDK FileKeyStore / Go FileKeyStore 对齐:
5
+ * - key.json / cert.pem 仍用文件存储
6
+ * - tokens / prekeys / group_secrets / sessions / instance_state / metadata_kv 全部存 SQLite
7
+ * - 废弃 meta.json
8
+ */
9
+ import type { KeyStore } from './index.js';
10
+ import type { SecretStore } from '../secret-store/index.js';
11
+ import { type GroupSecretRecord, type IdentityRecord, type KeyPairRecord, type MetadataRecord, type PrekeyMap, type PrekeyRecord } from '../types.js';
12
+ export declare class FileKeyStore implements KeyStore {
13
+ private _root;
14
+ private _aidsRoot;
15
+ private _secretStore;
16
+ private _aidDBs;
17
+ private _deviceId;
18
+ constructor(root?: string, opts?: {
19
+ secretStore?: SecretStore;
20
+ encryptionSeed?: string;
21
+ sqliteBackup?: unknown;
22
+ });
23
+ close(): void;
24
+ private _getDB;
25
+ private _prepareRoot;
26
+ loadKeyPair(aid: string): KeyPairRecord | null;
27
+ saveKeyPair(aid: string, keyPair: KeyPairRecord): void;
28
+ private _restoreKeyPair;
29
+ loadCert(aid: string, certFingerprint?: string): string | null;
30
+ saveCert(aid: string, certPem: string, certFingerprint?: string, opts?: {
31
+ makeActive?: boolean;
32
+ }): void;
33
+ loadIdentity(aid: string): IdentityRecord | null;
34
+ saveIdentity(aid: string, identity: IdentityRecord): void;
35
+ loadAnyIdentity(): IdentityRecord | null;
36
+ loadE2EEPrekeys(aid: string, deviceId?: string): PrekeyMap;
37
+ saveE2EEPrekey(aid: string, prekeyId: string, prekeyData: PrekeyRecord, deviceId?: string): void;
38
+ cleanupE2EEPrekeys(aid: string, cutoffMs: number, keepLatest?: number, deviceId?: string): string[];
39
+ listGroupSecretIds(aid: string): string[];
40
+ cleanupGroupOldEpochsState(aid: string, groupId: string, cutoffMs: number): number;
41
+ loadGroupSecretEpoch(aid: string, groupId: string, epoch?: number | null): GroupSecretRecord | null;
42
+ loadGroupSecretEpochs(aid: string, groupId: string): GroupSecretRecord[];
43
+ storeGroupSecretTransition(aid: string, groupId: string, opts: {
44
+ epoch: number;
45
+ secret: string;
46
+ commitment: string;
47
+ memberAids: string[];
48
+ epochChain?: string;
49
+ pendingRotationId?: string;
50
+ epochChainUnverified?: boolean | null;
51
+ epochChainUnverifiedReason?: string | null;
52
+ oldEpochRetentionMs: number;
53
+ }): boolean;
54
+ storeGroupSecretEpoch(aid: string, groupId: string, opts: {
55
+ epoch: number;
56
+ secret: string;
57
+ commitment: string;
58
+ memberAids: string[];
59
+ epochChain?: string;
60
+ pendingRotationId?: string;
61
+ epochChainUnverified?: boolean | null;
62
+ epochChainUnverifiedReason?: string | null;
63
+ oldEpochRetentionMs: number;
64
+ }): boolean;
65
+ discardPendingGroupSecretState(aid: string, groupId: string, epoch: number, rotationId: string): boolean;
66
+ deleteGroupSecretState(aid: string, groupId: string): void;
67
+ loadInstanceState(aid: string, deviceId: string, slotId?: string): MetadataRecord | null;
68
+ saveInstanceState(aid: string, deviceId: string, slotId: string, state: MetadataRecord): void;
69
+ updateInstanceState(aid: string, deviceId: string, slotId: string, updater: (state: MetadataRecord) => MetadataRecord | void): MetadataRecord;
70
+ loadE2EESessions(aid: string): Array<Record<string, unknown>>;
71
+ saveE2EESession(aid: string, sessionId: string, data: Record<string, unknown>): void;
72
+ saveSeq(aid: string, deviceId: string, slotId: string, namespace: string, contiguousSeq: number): void;
73
+ loadSeq(aid: string, deviceId: string, slotId: string, namespace: string): number;
74
+ loadAllSeqs(aid: string, deviceId: string, slotId: string): Record<string, number>;
75
+ /** 列出所有已存储的 AID(对齐 Python list_identities) */
76
+ listIdentities(): string[];
77
+ /** 加载指定 AID 的元数据(对齐 Python load_metadata) */
78
+ loadMetadata(aid: string): Record<string, unknown> | null;
79
+ private _keyPairPath;
80
+ private _certPath;
81
+ private _certVersionPath;
82
+ }
@@ -0,0 +1,395 @@
1
+ /**
2
+ * 基于文件(key.json/cert.pem)+ AIDDatabase(SQLite)的 KeyStore 实现。
3
+ *
4
+ * 与 Python SDK FileKeyStore / Go FileKeyStore 对齐:
5
+ * - key.json / cert.pem 仍用文件存储
6
+ * - tokens / prekeys / group_secrets / sessions / instance_state / metadata_kv 全部存 SQLite
7
+ * - 废弃 meta.json
8
+ */
9
+ import * as crypto from 'node:crypto';
10
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, chmodSync, renameSync, unlinkSync, } from 'node:fs';
11
+ import { join, dirname } from 'node:path';
12
+ import { homedir } from 'node:os';
13
+ import { AIDDatabase } from './aid-db.js';
14
+ import { getDeviceId } from '../config.js';
15
+ import { certificateSha256Fingerprint } from '../crypto.js';
16
+ import { createDefaultSecretStore } from '../secret-store/index.js';
17
+ import { isJsonObject, } from '../types.js';
18
+ const TOKEN_FIELDS = new Set(['access_token', 'refresh_token', 'kite_token']);
19
+ function secureFilePermissions(path) {
20
+ if (process.platform !== 'win32') {
21
+ try {
22
+ chmodSync(path, 0o600);
23
+ }
24
+ catch { /* ignore */ }
25
+ }
26
+ }
27
+ function deepClone(value) {
28
+ return JSON.parse(JSON.stringify(value));
29
+ }
30
+ function fingerprintFromCertPem(certPem) {
31
+ // 委托给 crypto.ts 的统一实现(ISSUE-SDK-TS-008: 消除两套指纹计算)
32
+ return certificateSha256Fingerprint(certPem);
33
+ }
34
+ function normalizeCertFingerprint(fp) {
35
+ const v = String(fp ?? '').trim().toLowerCase();
36
+ if (!v.startsWith('sha256:') || v.length !== 71)
37
+ return '';
38
+ if (/[^0-9a-f]/.test(v.slice(7)))
39
+ return '';
40
+ return v;
41
+ }
42
+ function safeAid(aid) {
43
+ return aid.replace(/[/\\:]/g, '_');
44
+ }
45
+ export class FileKeyStore {
46
+ _root;
47
+ _aidsRoot;
48
+ _secretStore;
49
+ _aidDBs = new Map();
50
+ _deviceId;
51
+ constructor(root, opts) {
52
+ const preferred = root ?? join(homedir(), '.aun');
53
+ const fallback = join(process.cwd(), '.aun');
54
+ this._root = this._prepareRoot(preferred, fallback);
55
+ this._secretStore = opts?.secretStore ?? createDefaultSecretStore(this._root, opts?.encryptionSeed);
56
+ this._aidsRoot = join(this._root, 'AIDs');
57
+ mkdirSync(this._aidsRoot, { recursive: true });
58
+ this._deviceId = getDeviceId(this._root);
59
+ }
60
+ close() {
61
+ for (const db of this._aidDBs.values())
62
+ db.close();
63
+ this._aidDBs.clear();
64
+ }
65
+ _getDB(aid) {
66
+ const safe = safeAid(aid);
67
+ let db = this._aidDBs.get(safe);
68
+ if (!db) {
69
+ const dbPath = join(this._aidsRoot, safe, 'aun.db');
70
+ try {
71
+ db = new AIDDatabase(dbPath, this._secretStore, safe);
72
+ }
73
+ catch (exc) {
74
+ // DB 损坏:备份后重建
75
+ console.warn('[aun_core.keystore] 数据库损坏,备份后重建');
76
+ const ts = new Date().toISOString().replace(/[:.]/g, '-');
77
+ const bakPath = dbPath + `.corrupt_${ts}.bak`;
78
+ try {
79
+ renameSync(dbPath, bakPath);
80
+ }
81
+ catch { /* 备份失败也继续重建 */ }
82
+ // 清理 WAL/SHM
83
+ for (const suffix of ['-wal', '-shm', '-journal']) {
84
+ try {
85
+ unlinkSync(dbPath + suffix);
86
+ }
87
+ catch { /* ignore */ }
88
+ }
89
+ db = new AIDDatabase(dbPath, this._secretStore, safe);
90
+ }
91
+ this._aidDBs.set(safe, db);
92
+ }
93
+ return db;
94
+ }
95
+ _prepareRoot(preferred, fallback) {
96
+ try {
97
+ mkdirSync(preferred, { recursive: true });
98
+ return preferred;
99
+ }
100
+ catch {
101
+ // ISSUE-TS-003: 回退时警告用户数据存储位置变更
102
+ console.warn(`[aun_core.keystore] 首选路径 ${preferred} 不可用,回退到 ${fallback}`);
103
+ mkdirSync(fallback, { recursive: true });
104
+ return fallback;
105
+ }
106
+ }
107
+ // ── KeyPair ──────────────────────────────────────────────
108
+ loadKeyPair(aid) {
109
+ const path = this._keyPairPath(aid);
110
+ if (!existsSync(path))
111
+ return null;
112
+ try {
113
+ const raw = JSON.parse(readFileSync(path, 'utf-8'));
114
+ return this._restoreKeyPair(aid, raw);
115
+ }
116
+ catch (exc) {
117
+ console.warn('[aun_core.keystore] key.json 读取或解析失败,视为不存在');
118
+ return null;
119
+ }
120
+ }
121
+ saveKeyPair(aid, keyPair) {
122
+ const path = this._keyPairPath(aid);
123
+ mkdirSync(dirname(path), { recursive: true });
124
+ const protected_ = deepClone(keyPair);
125
+ const pem = protected_.private_key_pem;
126
+ if (typeof pem === 'string' && pem) {
127
+ delete protected_.private_key_pem;
128
+ const rec = this._secretStore.protect(safeAid(aid), 'identity/private_key', Buffer.from(pem, 'utf-8'));
129
+ protected_.private_key_protection = rec;
130
+ }
131
+ writeFileSync(path, JSON.stringify(protected_, null, 2), { mode: 0o600 });
132
+ secureFilePermissions(path);
133
+ }
134
+ _restoreKeyPair(aid, kp) {
135
+ const out = deepClone(kp);
136
+ const rec = out.private_key_protection;
137
+ if (isJsonObject(rec)) {
138
+ const plain = this._secretStore.reveal(safeAid(aid), 'identity/private_key', rec);
139
+ if (plain)
140
+ out.private_key_pem = plain.toString('utf-8');
141
+ }
142
+ return out;
143
+ }
144
+ // ── Cert ─────────────────────────────────────────────────
145
+ loadCert(aid, certFingerprint) {
146
+ try {
147
+ const norm = normalizeCertFingerprint(certFingerprint);
148
+ if (norm) {
149
+ const vp = this._certVersionPath(aid, norm);
150
+ if (existsSync(vp))
151
+ return readFileSync(vp, 'utf-8');
152
+ const active = this._certPath(aid);
153
+ if (existsSync(active)) {
154
+ const certPem = readFileSync(active, 'utf-8');
155
+ if (fingerprintFromCertPem(certPem) === norm)
156
+ return certPem;
157
+ }
158
+ return null;
159
+ }
160
+ const path = this._certPath(aid);
161
+ return existsSync(path) ? readFileSync(path, 'utf-8') : null;
162
+ }
163
+ catch (exc) {
164
+ // 文件被锁定、无权限、目录冲突等异常时降级返回 null
165
+ console.warn('[aun_core.keystore] cert.pem 读取失败,视为不存在');
166
+ return null;
167
+ }
168
+ }
169
+ saveCert(aid, certPem, certFingerprint, opts) {
170
+ const norm = normalizeCertFingerprint(certFingerprint);
171
+ if (norm) {
172
+ const vp = this._certVersionPath(aid, norm);
173
+ mkdirSync(dirname(vp), { recursive: true });
174
+ writeFileSync(vp, certPem);
175
+ if (!opts?.makeActive)
176
+ return;
177
+ }
178
+ const path = this._certPath(aid);
179
+ mkdirSync(dirname(path), { recursive: true });
180
+ writeFileSync(path, certPem);
181
+ }
182
+ // ── Identity ─────────────────────────────────────────────
183
+ loadIdentity(aid) {
184
+ const kp = this.loadKeyPair(aid);
185
+ const cert = this.loadCert(aid);
186
+ // 直接从 DB 读取 tokens + KV
187
+ const db = this._getDB(aid);
188
+ const tokens = db.getAllTokens();
189
+ const kv = db.getAllMetadata();
190
+ const hasMeta = Object.keys(tokens).length > 0 || Object.keys(kv).length > 0;
191
+ if (!kp && !cert && !hasMeta)
192
+ return null;
193
+ const identity = {};
194
+ for (const [k, v] of Object.entries(kv)) {
195
+ try {
196
+ identity[k] = JSON.parse(v);
197
+ }
198
+ catch {
199
+ identity[k] = v;
200
+ }
201
+ }
202
+ Object.assign(identity, tokens);
203
+ if (kp)
204
+ Object.assign(identity, kp);
205
+ if (cert) {
206
+ // key/cert 公钥一致性校验:防止 cert.pem 被意外覆盖
207
+ const localPubB64 = kp?.public_key_der_b64;
208
+ if (typeof localPubB64 === 'string' && localPubB64) {
209
+ try {
210
+ const x = new crypto.X509Certificate(cert);
211
+ const certPubDer = x.publicKey.export({ type: 'spki', format: 'der' });
212
+ const localPubDer = Buffer.from(localPubB64, 'base64');
213
+ if (!certPubDer.equals(localPubDer)) {
214
+ console.error('[keystore] key.json 公钥与 cert.pem 公钥不匹配,丢弃 cert');
215
+ }
216
+ else {
217
+ identity.cert = cert;
218
+ }
219
+ }
220
+ catch {
221
+ identity.cert = cert;
222
+ }
223
+ }
224
+ else {
225
+ identity.cert = cert;
226
+ }
227
+ }
228
+ return identity;
229
+ }
230
+ saveIdentity(aid, identity) {
231
+ const kp = {};
232
+ for (const k of ['private_key_pem', 'public_key_der_b64', 'curve']) {
233
+ if (k in identity)
234
+ kp[k] = identity[k];
235
+ }
236
+ if (Object.keys(kp).length > 0)
237
+ this.saveKeyPair(aid, kp);
238
+ if (typeof identity.cert === 'string' && identity.cert)
239
+ this.saveCert(aid, identity.cert);
240
+ // 直接写入 tokens + KV
241
+ const db = this._getDB(aid);
242
+ const skip = new Set([...TOKEN_FIELDS, 'private_key_pem', 'public_key_der_b64', 'curve', 'cert', 'e2ee_prekeys', 'group_secrets', 'e2ee_sessions']);
243
+ for (const field of TOKEN_FIELDS) {
244
+ if (!(field in identity))
245
+ continue;
246
+ const v = identity[field];
247
+ if (typeof v === 'string' && v)
248
+ db.setToken(field, v);
249
+ else
250
+ db.deleteToken(field);
251
+ }
252
+ for (const [k, v] of Object.entries(identity)) {
253
+ if (skip.has(k))
254
+ continue;
255
+ db.setMetadata(k, JSON.stringify(v));
256
+ }
257
+ }
258
+ loadAnyIdentity() {
259
+ if (!existsSync(this._aidsRoot))
260
+ return null;
261
+ for (const entry of readdirSync(this._aidsRoot, { withFileTypes: true })) {
262
+ if (!entry.isDirectory())
263
+ continue;
264
+ const identity = this.loadIdentity(entry.name);
265
+ if (identity)
266
+ return identity;
267
+ }
268
+ return null;
269
+ }
270
+ // ── Prekeys ──────────────────────────────────────────────
271
+ loadE2EEPrekeys(aid, deviceId) {
272
+ return this._getDB(aid).loadPrekeys(String(deviceId ?? '').trim());
273
+ }
274
+ saveE2EEPrekey(aid, prekeyId, prekeyData, deviceId) {
275
+ const pem = typeof prekeyData.private_key_pem === 'string' ? prekeyData.private_key_pem : '';
276
+ const extra = {};
277
+ for (const [k, v] of Object.entries(prekeyData)) {
278
+ if (!['private_key_pem', 'created_at', 'updated_at', 'expires_at'].includes(k))
279
+ extra[k] = v;
280
+ }
281
+ this._getDB(aid).savePrekey(prekeyId, pem, String(deviceId ?? '').trim(), prekeyData.created_at, prekeyData.expires_at, extra);
282
+ }
283
+ cleanupE2EEPrekeys(aid, cutoffMs, keepLatest = 7, deviceId) {
284
+ return this._getDB(aid).cleanupPrekeys(String(deviceId ?? '').trim(), cutoffMs, keepLatest);
285
+ }
286
+ // ── Group Secrets ────────────────────────────────────────
287
+ listGroupSecretIds(aid) {
288
+ const db = this._getDB(aid);
289
+ const ids = new Set(Object.keys(db.loadAllGroupCurrent()));
290
+ for (const groupId of db.loadAllGroupIdsWithOldEpochs())
291
+ ids.add(groupId);
292
+ return [...ids].sort();
293
+ }
294
+ cleanupGroupOldEpochsState(aid, groupId, cutoffMs) {
295
+ return this._getDB(aid).cleanupGroupOldEpochs(groupId, cutoffMs);
296
+ }
297
+ loadGroupSecretEpoch(aid, groupId, epoch) {
298
+ return this._getDB(aid).loadGroupSecretEpoch(groupId, epoch);
299
+ }
300
+ loadGroupSecretEpochs(aid, groupId) {
301
+ return this._getDB(aid).loadGroupSecretEpochs(groupId);
302
+ }
303
+ storeGroupSecretTransition(aid, groupId, opts) {
304
+ return this._getDB(aid).storeGroupSecretTransition(groupId, opts);
305
+ }
306
+ storeGroupSecretEpoch(aid, groupId, opts) {
307
+ return this._getDB(aid).storeGroupSecretEpoch(groupId, opts);
308
+ }
309
+ discardPendingGroupSecretState(aid, groupId, epoch, rotationId) {
310
+ return this._getDB(aid).discardPendingGroupSecretState(groupId, epoch, rotationId);
311
+ }
312
+ deleteGroupSecretState(aid, groupId) {
313
+ const db = this._getDB(aid);
314
+ db.deleteGroupCurrent(groupId);
315
+ db.deleteAllGroupOldEpochs(groupId);
316
+ }
317
+ // ── Instance State ───────────────────────────────────────
318
+ loadInstanceState(aid, deviceId, slotId = '') {
319
+ return this._getDB(aid).loadInstanceState(deviceId, slotId);
320
+ }
321
+ saveInstanceState(aid, deviceId, slotId, state) {
322
+ this._getDB(aid).saveInstanceState(deviceId, slotId, state);
323
+ }
324
+ updateInstanceState(aid, deviceId, slotId, updater) {
325
+ const db = this._getDB(aid);
326
+ const current = (db.loadInstanceState(deviceId, slotId) ?? {});
327
+ const working = deepClone(current);
328
+ const updated = updater(working) ?? working;
329
+ db.saveInstanceState(deviceId, slotId, updated);
330
+ return deepClone(updated);
331
+ }
332
+ // ── E2EE Sessions ────────────────────────────────────────
333
+ loadE2EESessions(aid) {
334
+ return this._getDB(aid).loadAllSessions();
335
+ }
336
+ saveE2EESession(aid, sessionId, data) {
337
+ this._getDB(aid).saveSession(sessionId, data);
338
+ }
339
+ // ── Seq Tracker ───────────────────────────────────────────
340
+ saveSeq(aid, deviceId, slotId, namespace, contiguousSeq) {
341
+ this._getDB(aid).saveSeq(deviceId, slotId, namespace, contiguousSeq);
342
+ }
343
+ loadSeq(aid, deviceId, slotId, namespace) {
344
+ return this._getDB(aid).loadSeq(deviceId, slotId, namespace);
345
+ }
346
+ loadAllSeqs(aid, deviceId, slotId) {
347
+ return this._getDB(aid).loadAllSeqs(deviceId, slotId);
348
+ }
349
+ // ── 身份列表 ───────────────────────────────────────────
350
+ /** 列出所有已存储的 AID(对齐 Python list_identities) */
351
+ listIdentities() {
352
+ if (!existsSync(this._aidsRoot))
353
+ return [];
354
+ const aids = [];
355
+ for (const entry of readdirSync(this._aidsRoot, { withFileTypes: true })) {
356
+ if (!entry.isDirectory())
357
+ continue;
358
+ aids.push(entry.name);
359
+ }
360
+ return aids;
361
+ }
362
+ /** 加载指定 AID 的元数据(对齐 Python load_metadata) */
363
+ loadMetadata(aid) {
364
+ try {
365
+ const db = this._getDB(aid);
366
+ const kv = db.getAllMetadata();
367
+ if (Object.keys(kv).length === 0)
368
+ return null;
369
+ const result = {};
370
+ for (const [k, v] of Object.entries(kv)) {
371
+ try {
372
+ result[k] = JSON.parse(v);
373
+ }
374
+ catch {
375
+ result[k] = v;
376
+ }
377
+ }
378
+ return result;
379
+ }
380
+ catch {
381
+ return null;
382
+ }
383
+ }
384
+ // ── 路径辅助 ─────────────────────────────────────────────
385
+ _keyPairPath(aid) {
386
+ return join(this._aidsRoot, safeAid(aid), 'private', 'key.json');
387
+ }
388
+ _certPath(aid) {
389
+ return join(this._aidsRoot, safeAid(aid), 'public', 'cert.pem');
390
+ }
391
+ _certVersionPath(aid, fp) {
392
+ return join(this._aidsRoot, safeAid(aid), 'public', 'certs', `${fp.replace(/:/g, '_')}.pem`);
393
+ }
394
+ }
395
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/keystore/file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * KeyStore 接口定义
3
+ *
4
+ * 与 Python SDK 的 KeyStore Protocol 完全对齐。
5
+ */
6
+ import type { GroupSecretRecord, IdentityRecord, KeyPairRecord, MetadataRecord, PrekeyMap, PrekeyRecord } from '../types.js';
7
+ export interface KeyStore {
8
+ /** 加载密钥对 */
9
+ loadKeyPair(aid: string): KeyPairRecord | null;
10
+ /** 保存密钥对 */
11
+ saveKeyPair(aid: string, keyPair: KeyPairRecord): void;
12
+ /** 加载证书 */
13
+ loadCert(aid: string, certFingerprint?: string): string | null;
14
+ /** 保存证书 */
15
+ saveCert(aid: string, certPem: string, certFingerprint?: string, opts?: {
16
+ makeActive?: boolean;
17
+ }): void;
18
+ /** 加载完整身份信息 */
19
+ loadIdentity(aid: string): IdentityRecord | null;
20
+ /** 保存完整身份信息 */
21
+ saveIdentity(aid: string, identity: IdentityRecord): void;
22
+ /** 加载实例级状态 */
23
+ loadInstanceState?(aid: string, deviceId: string, slotId?: string): MetadataRecord | null;
24
+ /** 保存实例级状态 */
25
+ saveInstanceState?(aid: string, deviceId: string, slotId: string, state: MetadataRecord): void;
26
+ /** 原子更新实例级状态 */
27
+ updateInstanceState?(aid: string, deviceId: string, slotId: string, updater: (state: MetadataRecord) => MetadataRecord | void): MetadataRecord;
28
+ /** 加载结构化 prekeys,deviceId 为空时等价于全局 */
29
+ loadE2EEPrekeys?(aid: string, deviceId?: string): PrekeyMap;
30
+ /** 保存单个 prekey,deviceId 为空时等价于全局 */
31
+ saveE2EEPrekey?(aid: string, prekeyId: string, prekeyData: PrekeyRecord, deviceId?: string): void;
32
+ /** 清理过期 prekeys,deviceId 为空时等价于全局 */
33
+ cleanupE2EEPrekeys?(aid: string, cutoffMs: number, keepLatest?: number, deviceId?: string): string[];
34
+ /** 列出本地已存储群组密钥的 group_id */
35
+ listGroupSecretIds?(aid: string): string[];
36
+ /** 清理单个群组过期 old epochs */
37
+ cleanupGroupOldEpochsState?(aid: string, groupId: string, cutoffMs: number): number;
38
+ /** 按 row 加载当前或指定 epoch 的群组密钥 */
39
+ loadGroupSecretEpoch?(aid: string, groupId: string, epoch?: number | null): GroupSecretRecord | null;
40
+ /** 按 row 加载某个群组的当前和历史 epoch 密钥 */
41
+ loadGroupSecretEpochs?(aid: string, groupId: string): GroupSecretRecord[];
42
+ /** 事务化保存群组密钥状态转移 */
43
+ storeGroupSecretTransition?(aid: string, groupId: string, opts: {
44
+ epoch: number;
45
+ secret: string;
46
+ commitment: string;
47
+ memberAids: string[];
48
+ epochChain?: string;
49
+ pendingRotationId?: string;
50
+ epochChainUnverified?: boolean | null;
51
+ epochChainUnverifiedReason?: string | null;
52
+ oldEpochRetentionMs: number;
53
+ }): boolean;
54
+ /** 事务化保存指定 epoch 密钥;低于 current 时写入 old epoch row */
55
+ storeGroupSecretEpoch?(aid: string, groupId: string, opts: {
56
+ epoch: number;
57
+ secret: string;
58
+ commitment: string;
59
+ memberAids: string[];
60
+ epochChain?: string;
61
+ pendingRotationId?: string;
62
+ epochChainUnverified?: boolean | null;
63
+ epochChainUnverifiedReason?: string | null;
64
+ oldEpochRetentionMs: number;
65
+ }): boolean;
66
+ /** 事务化丢弃指定 pending rotation */
67
+ discardPendingGroupSecretState?(aid: string, groupId: string, epoch: number, rotationId: string): boolean;
68
+ /** 删除单个群组的所有密钥状态(群组解散时使用) */
69
+ deleteGroupSecretState?(aid: string, groupId: string): void;
70
+ /** 加载全部 E2EE sessions */
71
+ loadE2EESessions?(aid: string): Array<Record<string, unknown>>;
72
+ /** 保存单个 E2EE session */
73
+ saveE2EESession?(aid: string, sessionId: string, data: Record<string, unknown>): void;
74
+ /** 保存单个 namespace 的 contiguous_seq */
75
+ saveSeq?(aid: string, deviceId: string, slotId: string, namespace: string, contiguousSeq: number): void;
76
+ /** 加载单个 namespace 的 contiguous_seq */
77
+ loadSeq?(aid: string, deviceId: string, slotId: string, namespace: string): number;
78
+ /** 加载某 device+slot 下所有 namespace 的 contiguous_seq */
79
+ loadAllSeqs?(aid: string, deviceId: string, slotId: string): Record<string, number>;
80
+ /** 读取最近 ack seq,供 SeqTracker 作 baseline 使用 */
81
+ getLastAckSeq?(aid: string, deviceId: string, slotId: string, namespace: string): number;
82
+ /** 写入最近 ack seq */
83
+ setLastAckSeq?(aid: string, deviceId: string, slotId: string, namespace: string, seq: number): void;
84
+ /** 列出所有已存储的 AID(对齐 Python list_identities) */
85
+ listIdentities?(): string[];
86
+ /** 加载指定 AID 的元数据(对齐 Python load_metadata) */
87
+ loadMetadata?(aid: string): Record<string, unknown> | null;
88
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * KeyStore 接口定义
3
+ *
4
+ * 与 Python SDK 的 KeyStore Protocol 完全对齐。
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keystore/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * SQLite 备份层 + 结构化主存。
3
+ *
4
+ * 语义对齐 Python:
5
+ * - metadata 仍作为兼容备份;
6
+ * - prekeys / group_current / group_old_epochs 作为结构化主存;
7
+ * - 业务层优先读取结构化主存,metadata 仅作为兼容视图和未过期回捞来源。
8
+ */
9
+ import type { JsonObject } from '../types.js';
10
+ type JsonMap = JsonObject;
11
+ export declare class SQLiteBackup {
12
+ private _db;
13
+ private _available;
14
+ constructor(dbPath?: string);
15
+ get available(): boolean;
16
+ close(): void;
17
+ backupSeed(seed: Buffer): void;
18
+ restoreSeed(): Buffer | null;
19
+ backupDeviceId(deviceId: string): void;
20
+ restoreDeviceId(): string | null;
21
+ backupKeyPair(aid: string, data: string): void;
22
+ restoreKeyPair(aid: string): string | null;
23
+ backupCert(aid: string, certPem: string): void;
24
+ restoreCert(aid: string): string | null;
25
+ backupMetadata(aid: string, data: string): void;
26
+ restoreMetadata(aid: string): string | null;
27
+ loadPrekeys(aid: string): Record<string, JsonMap>;
28
+ replacePrekeys(aid: string, prekeys: Record<string, JsonMap>): void;
29
+ cleanupPrekeysBefore(aid: string, cutoffMs: number, keepLatest?: number): string[];
30
+ loadGroupEntries(aid: string): Record<string, JsonMap>;
31
+ replaceGroupEntries(aid: string, entries: Record<string, JsonMap>): void;
32
+ cleanupGroupOldEpochs(aid: string, groupId: string, cutoffMs: number): number[];
33
+ private _initTables;
34
+ private _migrate;
35
+ private _runTransaction;
36
+ private _exec;
37
+ private _queryOne;
38
+ private _queryAll;
39
+ }
40
+ export {};