@agentunion/fastaun-browser 0.4.8 → 0.4.9
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/CHANGELOG.md +17 -0
- package/_packed_docs/CHANGELOG.md +17 -0
- package/_packed_docs/INDEX.md +15 -9
- package/_packed_docs/KITE_DOCS_GUIDE.md +8 -7
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +5 -4
- package/_packed_docs/sdk/INDEX.md +15 -9
- package/_packed_docs/sdk/README.md +3 -2
- package/dist/bundle.js +529 -395
- package/dist/client/delivery.js +15 -15
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.d.ts.map +1 -1
- package/dist/client/group-state.js +13 -21
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/identity.d.ts.map +1 -1
- package/dist/client/identity.js +5 -11
- package/dist/client/identity.js.map +1 -1
- package/dist/client/lifecycle.d.ts +2 -0
- package/dist/client/lifecycle.d.ts.map +1 -1
- package/dist/client/lifecycle.js +86 -26
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +4 -1
- package/dist/client/rpc-pipeline.d.ts.map +1 -1
- package/dist/client/rpc-pipeline.js +131 -0
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/runtime.d.ts +84 -0
- package/dist/client/runtime.d.ts.map +1 -1
- package/dist/client/runtime.js +234 -0
- package/dist/client/runtime.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts.map +1 -1
- package/dist/client/v2-e2ee.js +8 -15
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +1 -33
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -307
- package/dist/client.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -146,7 +146,6 @@ function reconnectSleepDelaySeconds(baseDelay, maxBaseDelay) {
|
|
|
146
146
|
}
|
|
147
147
|
/** 对端证书缓存 TTL(秒) */
|
|
148
148
|
const PEER_CERT_CACHE_TTL = 3600;
|
|
149
|
-
const PEER_PREKEYS_CACHE_TTL = 3600;
|
|
150
149
|
/**
|
|
151
150
|
* 将 WebSocket URL 转为对应的 HTTP URL
|
|
152
151
|
*/
|
|
@@ -928,66 +927,11 @@ export class AUNClient {
|
|
|
928
927
|
}
|
|
929
928
|
/** 断开连接但保留本地状态,可再次 connect */
|
|
930
929
|
async disconnect() {
|
|
931
|
-
|
|
932
|
-
this._clientLog.debug(`disconnect enter: state=${this._state}`);
|
|
933
|
-
if (this._closing) {
|
|
934
|
-
this._clientLog.debug(`disconnect exit: elapsed=${Date.now() - tStart}ms reason=closing`);
|
|
935
|
-
return;
|
|
936
|
-
}
|
|
937
|
-
if (![
|
|
938
|
-
ConnectionState.AUTHENTICATED,
|
|
939
|
-
ConnectionState.CONNECTING,
|
|
940
|
-
ConnectionState.READY,
|
|
941
|
-
ConnectionState.RETRY_BACKOFF,
|
|
942
|
-
ConnectionState.RECONNECTING,
|
|
943
|
-
ConnectionState.CONNECTION_FAILED,
|
|
944
|
-
].includes(this.state)) {
|
|
945
|
-
this._clientLog.debug(`disconnect exit: elapsed=${Date.now() - tStart}ms reason=not_connected`);
|
|
946
|
-
return;
|
|
947
|
-
}
|
|
948
|
-
this._saveSeqTrackerState();
|
|
949
|
-
this._stopBackgroundTasks();
|
|
950
|
-
if (this._reconnectAbort) {
|
|
951
|
-
this._reconnectAbort.abort();
|
|
952
|
-
this._reconnectAbort = null;
|
|
953
|
-
this._reconnectActive = false;
|
|
954
|
-
}
|
|
955
|
-
await this._transport.close();
|
|
956
|
-
this._state = 'standby';
|
|
957
|
-
await this._dispatcher.publish('state_change', { state: this._publicState(this._state) });
|
|
958
|
-
this._clientLog.debug(`disconnect exit: elapsed=${Date.now() - tStart}ms`);
|
|
930
|
+
return this._lifecycle.disconnect();
|
|
959
931
|
}
|
|
960
932
|
/** 关闭连接 */
|
|
961
933
|
async close() {
|
|
962
|
-
|
|
963
|
-
this._clientLog.debug(`close enter: state=${this._state}`);
|
|
964
|
-
this._closing = true;
|
|
965
|
-
this._saveSeqTrackerState();
|
|
966
|
-
this._stopBackgroundTasks();
|
|
967
|
-
// 取消进行中的重连
|
|
968
|
-
if (this._reconnectAbort) {
|
|
969
|
-
this._reconnectAbort.abort();
|
|
970
|
-
this._reconnectAbort = null;
|
|
971
|
-
this._reconnectActive = false;
|
|
972
|
-
}
|
|
973
|
-
if (this._state === 'idle' || this._state === 'closed') {
|
|
974
|
-
this._state = 'closed';
|
|
975
|
-
this._resetSeqTrackingState();
|
|
976
|
-
this._clientLog.debug(`close exit: elapsed=${Date.now() - tStart}ms reason=already_idle`);
|
|
977
|
-
return;
|
|
978
|
-
}
|
|
979
|
-
// 关闭前通知服务端主动退出(best-effort,失败不阻塞)
|
|
980
|
-
try {
|
|
981
|
-
await this._transport.call('auth.logout', {});
|
|
982
|
-
}
|
|
983
|
-
catch {
|
|
984
|
-
// auth.logout 失败不影响关闭流程
|
|
985
|
-
}
|
|
986
|
-
await this._transport.close();
|
|
987
|
-
this._state = 'closed';
|
|
988
|
-
await this._dispatcher.publish('state_change', { state: this._publicState(this._state) });
|
|
989
|
-
this._resetSeqTrackingState();
|
|
990
|
-
this._clientLog.debug(`close exit: elapsed=${Date.now() - tStart}ms`);
|
|
934
|
+
return this._lifecycle.close();
|
|
991
935
|
}
|
|
992
936
|
// ── RPC ───────────────────────────────────────────
|
|
993
937
|
/**
|
|
@@ -997,136 +941,7 @@ export class AUNClient {
|
|
|
997
941
|
* 自动解密 message.pull/group.pull、Group E2EE 生命周期编排。
|
|
998
942
|
*/
|
|
999
943
|
async call(method, params) {
|
|
1000
|
-
|
|
1001
|
-
this._clientLog.debug(`call enter: method=${method}`);
|
|
1002
|
-
try {
|
|
1003
|
-
const result = await this._callImpl(method, params);
|
|
1004
|
-
this._clientLog.debug(`call exit: elapsed=${Date.now() - tStart}ms method=${method}`);
|
|
1005
|
-
return result;
|
|
1006
|
-
}
|
|
1007
|
-
catch (err) {
|
|
1008
|
-
this._clientLog.debug(`call exit (error): elapsed=${Date.now() - tStart}ms method=${method} err=${err instanceof Error ? err.message : String(err)}`);
|
|
1009
|
-
throw err;
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
async _callImpl(method, params) {
|
|
1013
|
-
const p = this._rpcPipeline.preflight(method, params).params;
|
|
1014
|
-
// 自动加密:message.send 默认加密(encrypt 默认 true)— V2-only
|
|
1015
|
-
if (method === 'message.send') {
|
|
1016
|
-
const encrypt = p.encrypt !== undefined ? p.encrypt : true;
|
|
1017
|
-
delete p.encrypt;
|
|
1018
|
-
if (encrypt) {
|
|
1019
|
-
await this._ensureV2SessionReady('message.send', 'V2 session not initialized; encrypted message.send requires V2 (V1 E2EE removed)');
|
|
1020
|
-
this._clientLog.debug('call route: message.send → V2 encrypted send');
|
|
1021
|
-
return await this._sendV2(String(p.to ?? ''), p.payload ?? {}, {
|
|
1022
|
-
messageId: String(p.message_id ?? '') || undefined,
|
|
1023
|
-
timestamp: p.timestamp,
|
|
1024
|
-
protectedHeaders: this._protectedHeadersFromParams(p),
|
|
1025
|
-
context: isJsonObject(p.context) ? p.context : undefined,
|
|
1026
|
-
});
|
|
1027
|
-
}
|
|
1028
|
-
// encrypt=false:明文走通用 RPC 路径;protected_headers/headers 是信封元数据,加密与否都保留
|
|
1029
|
-
this._maybeAppendEchoTraceSend(p);
|
|
1030
|
-
}
|
|
1031
|
-
// 自动加密:group.send 默认加密(encrypt 默认 true)— V2-only
|
|
1032
|
-
if (method === 'group.send') {
|
|
1033
|
-
const encrypt = p.encrypt !== undefined ? p.encrypt : true;
|
|
1034
|
-
delete p.encrypt;
|
|
1035
|
-
if (encrypt) {
|
|
1036
|
-
await this._ensureV2SessionReady('group.send', 'V2 session not initialized; encrypted group.send requires V2 (V1 E2EE removed)');
|
|
1037
|
-
this._clientLog.debug('call route: group.send → V2 encrypted send');
|
|
1038
|
-
return await this._sendGroupV2(String(p.group_id ?? ''), p.payload ?? {}, {
|
|
1039
|
-
messageId: String(p.message_id ?? '') || undefined,
|
|
1040
|
-
timestamp: p.timestamp,
|
|
1041
|
-
protectedHeaders: this._protectedHeadersFromParams(p),
|
|
1042
|
-
context: isJsonObject(p.context) ? p.context : undefined,
|
|
1043
|
-
});
|
|
1044
|
-
}
|
|
1045
|
-
this._maybeAppendEchoTraceSend(p);
|
|
1046
|
-
}
|
|
1047
|
-
if (method === 'group.thought.put') {
|
|
1048
|
-
const encrypt = p.encrypt !== undefined ? p.encrypt : true;
|
|
1049
|
-
delete p.encrypt;
|
|
1050
|
-
if (encrypt) {
|
|
1051
|
-
await this._ensureV2SessionReady('group.thought.put', 'V2 session not initialized; encrypted group.thought.put requires V2 (V1 E2EE removed)');
|
|
1052
|
-
this._clientLog.debug('call route: group.thought.put → V2 encrypted put');
|
|
1053
|
-
return this._putGroupThoughtEncryptedV2(p);
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
if (method === 'message.thought.put') {
|
|
1057
|
-
const encrypt = p.encrypt !== undefined ? p.encrypt : true;
|
|
1058
|
-
delete p.encrypt;
|
|
1059
|
-
if (encrypt) {
|
|
1060
|
-
await this._ensureV2SessionReady('message.thought.put', 'V2 session not initialized; encrypted message.thought.put requires V2 (V1 E2EE removed)');
|
|
1061
|
-
this._clientLog.debug('call route: message.thought.put → V2 encrypted put');
|
|
1062
|
-
return this._putMessageThoughtEncryptedV2(p);
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
// Pull Gate:序列化同一 key 的 pull 操作,防止并发重复拉取
|
|
1066
|
-
const pullGateKey = this._pullGateKeyForCall(method, p);
|
|
1067
|
-
if (pullGateKey) {
|
|
1068
|
-
return await this._runPullSerialized(pullGateKey, async () => {
|
|
1069
|
-
return await this._callImplInner(method, p);
|
|
1070
|
-
});
|
|
1071
|
-
}
|
|
1072
|
-
return await this._callImplInner(method, p);
|
|
1073
|
-
}
|
|
1074
|
-
/**
|
|
1075
|
-
* _callImpl 的内层:pull gate 之后的实际 RPC 分发逻辑。
|
|
1076
|
-
* 拆分出来以便 pull gate 包裹整个操作。
|
|
1077
|
-
*/
|
|
1078
|
-
async _callImplInner(method, p) {
|
|
1079
|
-
// message.pull:V2-only,按需初始化后走 V2 pull
|
|
1080
|
-
if (method === 'message.pull') {
|
|
1081
|
-
await this._ensureV2SessionReady('message.pull');
|
|
1082
|
-
this._clientLog.debug('call route: message.pull → V2 pull');
|
|
1083
|
-
const messages = await this._pullV2(Number(p.after_seq ?? 0) || 0, Number(p.limit ?? 50) || 50, { force: p.force === true });
|
|
1084
|
-
return { messages };
|
|
1085
|
-
}
|
|
1086
|
-
// message.ack:V2-only,按需初始化后走 V2 ack
|
|
1087
|
-
if (method === 'message.ack') {
|
|
1088
|
-
await this._ensureV2SessionReady('message.ack');
|
|
1089
|
-
this._clientLog.debug('call route: message.ack → V2 ack');
|
|
1090
|
-
return await this._ackV2(Number(p.seq ?? p.up_to_seq ?? 0) || undefined);
|
|
1091
|
-
}
|
|
1092
|
-
// group.pull:V2-only,按需初始化后走 V2 pull
|
|
1093
|
-
if (method === 'group.pull' && p.group_id) {
|
|
1094
|
-
await this._ensureV2SessionReady('group.pull');
|
|
1095
|
-
this._clientLog.debug('call route: group.pull → V2 pull');
|
|
1096
|
-
const hasExplicitAfterSeq = 'after_seq' in p || 'after_message_seq' in p;
|
|
1097
|
-
const cursorParams = this._explicitGroupCursorParams(p);
|
|
1098
|
-
const ownsCursor = Object.keys(cursorParams).length === 0 || this._groupCursorTargetsCurrentInstance(cursorParams);
|
|
1099
|
-
const pullOpts = {};
|
|
1100
|
-
if (hasExplicitAfterSeq)
|
|
1101
|
-
pullOpts.explicitAfterSeq = true;
|
|
1102
|
-
if (Object.keys(cursorParams).length > 0)
|
|
1103
|
-
pullOpts.cursorParams = cursorParams;
|
|
1104
|
-
if (!ownsCursor)
|
|
1105
|
-
pullOpts.ownsCursor = false;
|
|
1106
|
-
const messages = await this._pullGroupV2(String(p.group_id), Number(p.after_seq ?? p.after_message_seq ?? 0) || 0, Number(p.limit ?? 50) || 50, Object.keys(pullOpts).length > 0 ? pullOpts : undefined);
|
|
1107
|
-
return { messages };
|
|
1108
|
-
}
|
|
1109
|
-
// group.ack_messages:V2-only,按需初始化后走 V2 ack
|
|
1110
|
-
if (method === 'group.ack_messages' && p.group_id) {
|
|
1111
|
-
await this._ensureV2SessionReady('group.ack_messages');
|
|
1112
|
-
this._clientLog.debug('call route: group.ack_messages → V2 ack');
|
|
1113
|
-
const cursorParams = this._explicitGroupCursorParams(p);
|
|
1114
|
-
const ownsCursor = Object.keys(cursorParams).length === 0 || this._groupCursorTargetsCurrentInstance(cursorParams);
|
|
1115
|
-
if (!ownsCursor) {
|
|
1116
|
-
return await this._rawGroupAckMessages(p);
|
|
1117
|
-
}
|
|
1118
|
-
return await this._ackGroupV2(String(p.group_id), Number(p.seq ?? p.msg_seq ?? p.up_to_seq ?? 0) || undefined);
|
|
1119
|
-
}
|
|
1120
|
-
// 关键操作自动附加客户端签名
|
|
1121
|
-
await this._rpcPipeline.applyClientSignature(method, p);
|
|
1122
|
-
// P1-23: 非幂等方法使用更长超时
|
|
1123
|
-
const callTimeout = NON_IDEMPOTENT_METHODS.has(method) ? NON_IDEMPOTENT_TIMEOUT : undefined;
|
|
1124
|
-
let result = callTimeout
|
|
1125
|
-
? await this._transport.call(method, p, callTimeout)
|
|
1126
|
-
: await this._transport.call(method, p);
|
|
1127
|
-
result = await this._rpcPipeline.postprocessResult(method, p, result);
|
|
1128
|
-
// ── Group E2EE 自动编排已移除(V2-only:由 group.v2.bootstrap 驱动)────────
|
|
1129
|
-
return result;
|
|
944
|
+
return await this._rpcPipeline.call(method, params);
|
|
1130
945
|
}
|
|
1131
946
|
async _callRawV2Rpc(method, params) {
|
|
1132
947
|
const p = { ...(params ?? {}) };
|
|
@@ -1170,10 +985,6 @@ export class AUNClient {
|
|
|
1170
985
|
_onRawMessageReceived(data) {
|
|
1171
986
|
this._delivery.onRawMessageReceived(data);
|
|
1172
987
|
}
|
|
1173
|
-
/** 实际处理推送消息的异步任务(V2-only:明文消息直接透传,V2 加密消息走 _onV2PushNotification) */
|
|
1174
|
-
async _processAndPublishMessage(data) {
|
|
1175
|
-
return this._delivery.processAndPublishMessage(data);
|
|
1176
|
-
}
|
|
1177
988
|
/** 处理群组消息推送:re-publish(V2 加密消息走 V2 push 路径) */
|
|
1178
989
|
_onRawGroupMessageCreated(data) {
|
|
1179
990
|
return this._delivery.onRawGroupMessageCreated(data);
|
|
@@ -1182,43 +993,19 @@ export class AUNClient {
|
|
|
1182
993
|
async _onRawGroupV2MessageCreated(data) {
|
|
1183
994
|
return this._delivery.onRawGroupV2MessageCreated(data);
|
|
1184
995
|
}
|
|
1185
|
-
/**
|
|
1186
|
-
* 处理群组推送消息的异步任务(V2-only:明文消息直接透传)。
|
|
1187
|
-
*
|
|
1188
|
-
* 带 payload 的事件(消息推送):直接 re-publish。
|
|
1189
|
-
* 不带 payload 的事件(通知):自动 pull 最新消息。
|
|
1190
|
-
*/
|
|
1191
|
-
async _processAndPublishGroupMessage(data) {
|
|
1192
|
-
return this._delivery.processAndPublishGroupMessage(data);
|
|
1193
|
-
}
|
|
1194
996
|
async _publishEncryptedPushMessage(normalEvent, undecryptableEvent, ns, seq, msg, group) {
|
|
1195
997
|
return await this._v2E2EE.publishEncryptedPushMessage(normalEvent, undecryptableEvent, ns, seq, msg, group);
|
|
1196
998
|
}
|
|
1197
999
|
async _decryptV2PushMessage(data) {
|
|
1198
1000
|
return await this._v2E2EE.decryptV2PushMessage(data);
|
|
1199
1001
|
}
|
|
1200
|
-
/** 后台补齐群消息空洞 */
|
|
1201
|
-
async _fillGroupGap(groupId) {
|
|
1202
|
-
return this._delivery.fillGroupGap(groupId);
|
|
1203
|
-
}
|
|
1204
|
-
/** 后台补齐群事件空洞 */
|
|
1205
|
-
async _fillGroupEventGap(groupId) {
|
|
1206
|
-
return this._delivery.fillGroupEventGap(groupId);
|
|
1207
|
-
}
|
|
1208
1002
|
/** 后台补齐 P2P 消息空洞 */
|
|
1209
1003
|
async _fillP2pGap() {
|
|
1210
1004
|
return this._delivery.fillP2pGap();
|
|
1211
1005
|
}
|
|
1212
|
-
/** 只按硬上限裁剪 published guard,不能按 contiguousSeq 清理。 */
|
|
1213
|
-
_prunePushedSeqs(ns) {
|
|
1214
|
-
this._delivery.prunePushedSeqs(ns);
|
|
1215
|
-
}
|
|
1216
1006
|
_markPublishedSeq(ns, seq) {
|
|
1217
1007
|
this._delivery.markPublishedSeq(ns, seq);
|
|
1218
1008
|
}
|
|
1219
|
-
_attachCurrentInstanceContext(payload) {
|
|
1220
|
-
return this._delivery.attachCurrentInstanceContext(payload);
|
|
1221
|
-
}
|
|
1222
1009
|
async _publishAppEvent(event, payload) {
|
|
1223
1010
|
await this._delivery.publishAppEvent(event, payload);
|
|
1224
1011
|
}
|
|
@@ -1261,9 +1048,6 @@ export class AUNClient {
|
|
|
1261
1048
|
const trace = `${this._echoTimestamp()} [AUN-SDK.receive] aid=${this._aid ?? '-'} conn_uptime=${uptime}s`;
|
|
1262
1049
|
msg.payload = { ...payload, text: payload.text + '\n' + trace };
|
|
1263
1050
|
}
|
|
1264
|
-
_messageTargetsCurrentInstance(message) {
|
|
1265
|
-
return this._delivery.messageTargetsCurrentInstance(message);
|
|
1266
|
-
}
|
|
1267
1051
|
async _drainOrderedMessages(ns, beforeSeq) {
|
|
1268
1052
|
await this._delivery.drainOrderedMessages(ns, beforeSeq);
|
|
1269
1053
|
}
|
|
@@ -1420,82 +1204,6 @@ export class AUNClient {
|
|
|
1420
1204
|
const digest = await crypto.subtle.digest('SHA-256', certBytes);
|
|
1421
1205
|
return 'sha256:' + Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
1422
1206
|
}
|
|
1423
|
-
/**
|
|
1424
|
-
* 从 X.509 DER 证书中提取 SubjectPublicKeyInfo 并计算其 SHA-256 指纹。
|
|
1425
|
-
* 返回 "sha256:<hex>",提取失败返回空串。
|
|
1426
|
-
* 用于 H7 指纹校验(DER 证书指纹 OR SPKI 指纹任一匹配)。
|
|
1427
|
-
*/
|
|
1428
|
-
async _spkiFingerprint(certPem) {
|
|
1429
|
-
try {
|
|
1430
|
-
const der = new Uint8Array(pemToArrayBuffer(certPem));
|
|
1431
|
-
// X.509: Certificate ::= SEQUENCE { tbsCertificate, signatureAlgorithm, signatureValue }
|
|
1432
|
-
// tbsCertificate ::= SEQUENCE { version?, serialNumber, signature, issuer, validity, subject, subjectPublicKeyInfo, ... }
|
|
1433
|
-
// 逐级解析 SEQUENCE 并定位 SPKI (第 7 个或第 6 个子元素,取决于 version 是否 [0] explicit)。
|
|
1434
|
-
const readLen = (buf, pos) => {
|
|
1435
|
-
const first = buf[pos];
|
|
1436
|
-
if (first < 0x80)
|
|
1437
|
-
return { len: first, next: pos + 1 };
|
|
1438
|
-
const n = first & 0x7f;
|
|
1439
|
-
let len = 0;
|
|
1440
|
-
for (let i = 0; i < n; i++)
|
|
1441
|
-
len = (len << 8) | buf[pos + 1 + i];
|
|
1442
|
-
return { len, next: pos + 1 + n };
|
|
1443
|
-
};
|
|
1444
|
-
// 外层 SEQUENCE
|
|
1445
|
-
if (der[0] !== 0x30)
|
|
1446
|
-
return '';
|
|
1447
|
-
const outer = readLen(der, 1);
|
|
1448
|
-
// tbsCertificate SEQUENCE 起点
|
|
1449
|
-
const tbsStart = outer.next;
|
|
1450
|
-
if (der[tbsStart] !== 0x30)
|
|
1451
|
-
return '';
|
|
1452
|
-
const tbsLen = readLen(der, tbsStart + 1);
|
|
1453
|
-
let p = tbsLen.next;
|
|
1454
|
-
const tbsEnd = tbsLen.next + tbsLen.len;
|
|
1455
|
-
// 跳过 [0] EXPLICIT Version(可选)
|
|
1456
|
-
if (der[p] === 0xa0) {
|
|
1457
|
-
const lv = readLen(der, p + 1);
|
|
1458
|
-
p = lv.next + lv.len;
|
|
1459
|
-
}
|
|
1460
|
-
// 跳过 serialNumber (INTEGER)
|
|
1461
|
-
if (der[p] !== 0x02)
|
|
1462
|
-
return '';
|
|
1463
|
-
let lv = readLen(der, p + 1);
|
|
1464
|
-
p = lv.next + lv.len;
|
|
1465
|
-
// 跳过 signature (SEQUENCE)
|
|
1466
|
-
if (der[p] !== 0x30)
|
|
1467
|
-
return '';
|
|
1468
|
-
lv = readLen(der, p + 1);
|
|
1469
|
-
p = lv.next + lv.len;
|
|
1470
|
-
// 跳过 issuer (SEQUENCE)
|
|
1471
|
-
if (der[p] !== 0x30)
|
|
1472
|
-
return '';
|
|
1473
|
-
lv = readLen(der, p + 1);
|
|
1474
|
-
p = lv.next + lv.len;
|
|
1475
|
-
// 跳过 validity (SEQUENCE)
|
|
1476
|
-
if (der[p] !== 0x30)
|
|
1477
|
-
return '';
|
|
1478
|
-
lv = readLen(der, p + 1);
|
|
1479
|
-
p = lv.next + lv.len;
|
|
1480
|
-
// 跳过 subject (SEQUENCE)
|
|
1481
|
-
if (der[p] !== 0x30)
|
|
1482
|
-
return '';
|
|
1483
|
-
lv = readLen(der, p + 1);
|
|
1484
|
-
p = lv.next + lv.len;
|
|
1485
|
-
// subjectPublicKeyInfo (SEQUENCE) — 连同 tag+length+value 全部即 SPKI DER
|
|
1486
|
-
if (der[p] !== 0x30 || p >= tbsEnd)
|
|
1487
|
-
return '';
|
|
1488
|
-
const spkiStart = p;
|
|
1489
|
-
const spkiLV = readLen(der, p + 1);
|
|
1490
|
-
const spkiEnd = spkiLV.next + spkiLV.len;
|
|
1491
|
-
const spkiDer = der.subarray(spkiStart, spkiEnd);
|
|
1492
|
-
const digest = await crypto.subtle.digest('SHA-256', spkiDer);
|
|
1493
|
-
return 'sha256:' + Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
1494
|
-
}
|
|
1495
|
-
catch {
|
|
1496
|
-
return '';
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
1207
|
async _decryptGroupThoughts(result) {
|
|
1500
1208
|
return await this._v2E2EE.decryptGroupThoughts(result);
|
|
1501
1209
|
}
|
|
@@ -2046,12 +1754,6 @@ export class AUNClient {
|
|
|
2046
1754
|
_validateMessageRecipient(toAid) {
|
|
2047
1755
|
this._rpcPipeline.validateMessageRecipient(toAid);
|
|
2048
1756
|
}
|
|
2049
|
-
_validateOutboundCall(method, params) {
|
|
2050
|
-
this._rpcPipeline.validateOutboundCall(method, params);
|
|
2051
|
-
}
|
|
2052
|
-
_injectMessageCursorContext(method, params) {
|
|
2053
|
-
this._rpcPipeline.injectMessageCursorContext(method, params);
|
|
2054
|
-
}
|
|
2055
1757
|
// ── 内部:断线重连 ────────────────────────────────
|
|
2056
1758
|
/** 不重连 close code 集合:认证失败/权限错误/被踢等,重连无意义 */
|
|
2057
1759
|
static _NO_RECONNECT_CODES = new Set([4001, 4003, 4008, 4009, 4010, 4011, 4012, 4013, 4014, 4015]);
|
|
@@ -2454,9 +2156,6 @@ export class AUNClient {
|
|
|
2454
2156
|
_scheduleV2SenderIKPending(args) {
|
|
2455
2157
|
return this._v2E2EE.scheduleSenderIKPending(args);
|
|
2456
2158
|
}
|
|
2457
|
-
async _resolveV2SenderIKPending(fromAid, senderDeviceId, groupId, fetchKey) {
|
|
2458
|
-
return await this._v2E2EE.resolveSenderIKPending(fromAid, senderDeviceId, groupId, fetchKey);
|
|
2459
|
-
}
|
|
2460
2159
|
/**
|
|
2461
2160
|
* V2 P2P 加密发送(推测性:用缓存 bootstrap 直接发,失败刷新重试一次)。
|
|
2462
2161
|
*
|
|
@@ -2826,9 +2525,6 @@ export class AUNClient {
|
|
|
2826
2525
|
&& (!slotId || slotId === (this._slotId ?? ''));
|
|
2827
2526
|
}
|
|
2828
2527
|
// ── Pull Gate(序列化同一 key 的并发 pull)──────────────────
|
|
2829
|
-
_pullGateKeyForCall(method, params) {
|
|
2830
|
-
return this._rpcPipeline.pullGateKeyForCall(method, params);
|
|
2831
|
-
}
|
|
2832
2528
|
async _runPullSerialized(key, operation) {
|
|
2833
2529
|
return await this._rpcPipeline.runPullSerialized(key, operation);
|
|
2834
2530
|
}
|