@onekeyfe/hd-core 1.2.2-alpha.10 → 1.2.2-alpha.11
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/__tests__/logBlockEvent.test.ts +45 -122
- package/__tests__/open-wallet-session.test.ts +53 -0
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/index.js +20 -75
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/events/logBlockEvent.ts +6 -75
- package/src/protocols/protocol-v2/walletSession.ts +7 -2
|
@@ -7,36 +7,6 @@ import {
|
|
|
7
7
|
} from '../src/events';
|
|
8
8
|
|
|
9
9
|
describe('getLogBlockLabel', () => {
|
|
10
|
-
it('blocks evmSignTypedData params before logging large typed data', () => {
|
|
11
|
-
expect(
|
|
12
|
-
getLogBlockLabel({
|
|
13
|
-
method: 'evmSignTypedData',
|
|
14
|
-
data: {
|
|
15
|
-
message: {
|
|
16
|
-
data: `0x${'ab'.repeat(4096)}`,
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
})
|
|
20
|
-
).toBe('evmSignTypedData');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('blocks evmSignTypedData iframe call payload before bridge logging', () => {
|
|
24
|
-
expect(
|
|
25
|
-
getLogBlockLabel({
|
|
26
|
-
event: 'iframe-call',
|
|
27
|
-
type: 'iframe-call',
|
|
28
|
-
payload: {
|
|
29
|
-
method: 'evmSignTypedData',
|
|
30
|
-
data: {
|
|
31
|
-
message: {
|
|
32
|
-
data: `0x${'ab'.repeat(4096)}`,
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
})
|
|
37
|
-
).toBe('evmSignTypedData');
|
|
38
|
-
});
|
|
39
|
-
|
|
40
10
|
it('keeps existing sensitive UI response blocking', () => {
|
|
41
11
|
expect(getLogBlockLabel({ type: UI_RESPONSE.RECEIVE_PIN })).toBe(UI_RESPONSE.RECEIVE_PIN);
|
|
42
12
|
});
|
|
@@ -53,119 +23,72 @@ describe('getLogBlockLabel', () => {
|
|
|
53
23
|
},
|
|
54
24
|
})
|
|
55
25
|
).toBe(type);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
expect(
|
|
69
|
-
getLogBlockLabel({
|
|
70
|
-
event: 'iframe-call',
|
|
71
|
-
type: 'iframe-call',
|
|
72
|
-
payload,
|
|
73
|
-
})
|
|
74
|
-
).toBe('openWalletSession');
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('keeps openWalletSession metadata while redacting wallet session identifiers', () => {
|
|
78
|
-
const safeResponse = getSafeLogPayload(
|
|
79
|
-
{
|
|
80
|
-
success: true,
|
|
81
|
-
payload: {
|
|
82
|
-
protocol: 'V2',
|
|
83
|
-
walletType: 'hidden',
|
|
84
|
-
deviceId: 'device-id',
|
|
85
|
-
passphraseState: 'wallet-identifier',
|
|
86
|
-
sessionId: 'wallet-session-id',
|
|
87
|
-
resumed: false,
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
'openWalletSession'
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
expect(safeResponse).toEqual({
|
|
94
|
-
method: 'openWalletSession',
|
|
95
|
-
success: true,
|
|
96
|
-
payload: {
|
|
97
|
-
protocol: 'V2',
|
|
98
|
-
walletType: 'hidden',
|
|
99
|
-
deviceId: 'device-id',
|
|
100
|
-
passphraseState: '[REDACTED]',
|
|
101
|
-
sessionId: '[REDACTED]',
|
|
102
|
-
resumed: false,
|
|
103
|
-
},
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it.each(['deviceUploadNft', 'deviceUploadWallpaper', 'uploadPortfolio'])(
|
|
108
|
-
'skips large Base64 resource payload logging for %s',
|
|
109
|
-
method => {
|
|
110
|
-
const request = { method, path: 'resource.bin', data: 'A'.repeat(1024 * 1024) };
|
|
111
|
-
expect(getLogBlockLabel(request)).toBe(method);
|
|
112
|
-
expect(getSafeLogPayload(request, method)).toEqual({
|
|
113
|
-
method,
|
|
26
|
+
expect(
|
|
27
|
+
getSafeLogPayload(
|
|
28
|
+
{
|
|
29
|
+
type,
|
|
30
|
+
payload: {
|
|
31
|
+
passphraseState: 'wallet-identifier',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
type
|
|
35
|
+
)
|
|
36
|
+
).toEqual({
|
|
37
|
+
method: type,
|
|
114
38
|
payload: '[REDACTED]',
|
|
115
39
|
});
|
|
116
40
|
}
|
|
117
41
|
);
|
|
118
42
|
|
|
119
|
-
it.each(['fileWrite', 'fileRead'])(
|
|
120
|
-
'
|
|
43
|
+
it.each(['deviceUploadNft', 'deviceUploadWallpaper', 'uploadPortfolio', 'fileWrite', 'fileRead'])(
|
|
44
|
+
'skips large resource or binary payload logging for %s',
|
|
121
45
|
method => {
|
|
122
|
-
const request = { method, path: 'resource.bin', data:
|
|
46
|
+
const request = { method, path: 'resource.bin', data: 'A'.repeat(1024) };
|
|
123
47
|
expect(getLogBlockLabel(request)).toBe(method);
|
|
124
48
|
expect(getSafeLogPayload(request, method)).toEqual({
|
|
125
49
|
method,
|
|
126
|
-
|
|
127
|
-
data: '[BINARY:1024]',
|
|
50
|
+
payload: '[REDACTED]',
|
|
128
51
|
});
|
|
129
52
|
}
|
|
130
53
|
);
|
|
131
54
|
|
|
132
|
-
it
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
55
|
+
it('logs signing requests and responses as-is', () => {
|
|
56
|
+
const request = {
|
|
57
|
+
method: 'btcSignMessage',
|
|
58
|
+
path: "m/44'/0'/0'/0/0",
|
|
59
|
+
messageHex: '68656c6c6f',
|
|
60
|
+
coin: 'Bitcoin',
|
|
61
|
+
};
|
|
62
|
+
const iframeRequest = {
|
|
63
|
+
event: 'iframe-call',
|
|
64
|
+
payload: request,
|
|
65
|
+
};
|
|
66
|
+
const response = {
|
|
67
|
+
success: true,
|
|
68
|
+
payload: {
|
|
69
|
+
signature: 'signature-bytes',
|
|
70
|
+
address: 'bc1qexample',
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
expect(getLogBlockLabel(request)).toBeUndefined();
|
|
75
|
+
expect(getLogBlockLabel(iframeRequest)).toBeUndefined();
|
|
76
|
+
expect(getSafeLogPayload(request)).toBe(request);
|
|
77
|
+
expect(getSafeLogPayload(response)).toBe(response);
|
|
78
|
+
});
|
|
144
79
|
|
|
145
80
|
it('keeps ordinary API requests and responses visible', () => {
|
|
146
81
|
const request = { method: 'getDeviceState', connectId: 'connect-id', scope: 'runtime' };
|
|
147
82
|
const response = { success: true, payload: { protocol: 'V2', initialized: true } };
|
|
148
83
|
|
|
149
84
|
expect(getLogBlockLabel(request)).toBeUndefined();
|
|
150
|
-
expect(getSafeLogPayload(request)).
|
|
151
|
-
expect(getSafeLogPayload(response)).
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it('redacts sensitive keys even for ordinary API payloads', () => {
|
|
155
|
-
expect(
|
|
156
|
-
getSafeLogPayload({
|
|
157
|
-
method: 'ordinaryMethod',
|
|
158
|
-
payload: { session_id: 'session-secret', nested: { pin: '1234' } },
|
|
159
|
-
})
|
|
160
|
-
).toEqual({
|
|
161
|
-
method: 'ordinaryMethod',
|
|
162
|
-
payload: { session_id: '[REDACTED]', nested: { pin: '[REDACTED]' } },
|
|
163
|
-
});
|
|
85
|
+
expect(getSafeLogPayload(request)).toBe(request);
|
|
86
|
+
expect(getSafeLogPayload(response)).toBe(response);
|
|
164
87
|
});
|
|
165
88
|
|
|
166
|
-
it('puts
|
|
167
|
-
expect(formatLogMethodLabel('response:', '
|
|
168
|
-
'response: [
|
|
89
|
+
it('puts blocked method names in the log label', () => {
|
|
90
|
+
expect(formatLogMethodLabel('response:', 'deviceUploadNft')).toBe(
|
|
91
|
+
'response: [deviceUploadNft]'
|
|
169
92
|
);
|
|
170
93
|
expect(formatLogMethodLabel('response:')).toBe('response:');
|
|
171
94
|
});
|
|
@@ -2080,6 +2080,59 @@ describe('openWalletSession', () => {
|
|
|
2080
2080
|
expect(deviceWalletSessionStore.get('device-1', 'hidden-state')).toBe('renewed-session');
|
|
2081
2081
|
});
|
|
2082
2082
|
|
|
2083
|
+
test('recovers the current Attach PIN wallet when the cached session is invalid', async () => {
|
|
2084
|
+
const typedCall = jest
|
|
2085
|
+
.fn()
|
|
2086
|
+
.mockResolvedValueOnce({ message: { version: 2 } })
|
|
2087
|
+
.mockRejectedValueOnce(
|
|
2088
|
+
Object.assign(new Error('Invalid session'), {
|
|
2089
|
+
errorCode: HardwareErrorCode.WalletSessionInvalid,
|
|
2090
|
+
})
|
|
2091
|
+
)
|
|
2092
|
+
.mockResolvedValueOnce({
|
|
2093
|
+
message: {
|
|
2094
|
+
btc_test_address: 'hidden-state',
|
|
2095
|
+
session_id: 'renewed-session',
|
|
2096
|
+
},
|
|
2097
|
+
});
|
|
2098
|
+
const promptPassphrase = jest.fn();
|
|
2099
|
+
const method = new OpenWalletSession({
|
|
2100
|
+
payload: {
|
|
2101
|
+
method: 'openWalletSession',
|
|
2102
|
+
connectId: 'connect-id',
|
|
2103
|
+
mode: 'resume-hidden',
|
|
2104
|
+
deviceId: 'device-1',
|
|
2105
|
+
passphraseState: 'hidden-state',
|
|
2106
|
+
},
|
|
2107
|
+
});
|
|
2108
|
+
method.init();
|
|
2109
|
+
deviceWalletSessionStore.set('device-1', 'hidden-state', 'expired-session');
|
|
2110
|
+
const device = createDevice({ unlockedAttachPin: true, typedCall, promptPassphrase });
|
|
2111
|
+
method.device = device as any;
|
|
2112
|
+
|
|
2113
|
+
await expect(method.run()).resolves.toEqual({
|
|
2114
|
+
protocol: 'V2',
|
|
2115
|
+
walletType: 'hidden',
|
|
2116
|
+
deviceId: 'device-1',
|
|
2117
|
+
passphraseState: 'hidden-state',
|
|
2118
|
+
resumed: false,
|
|
2119
|
+
});
|
|
2120
|
+
expect(typedCall.mock.calls.filter(call => call[0] === 'DeviceSessionGet')).toEqual([
|
|
2121
|
+
[
|
|
2122
|
+
'DeviceSessionGet',
|
|
2123
|
+
'DeviceSession',
|
|
2124
|
+
{
|
|
2125
|
+
session_id: 'expired-session',
|
|
2126
|
+
btc_test_address: 'hidden-state',
|
|
2127
|
+
},
|
|
2128
|
+
],
|
|
2129
|
+
['DeviceSessionGet', 'DeviceSession', {}],
|
|
2130
|
+
]);
|
|
2131
|
+
expect(promptPassphrase).not.toHaveBeenCalled();
|
|
2132
|
+
expect(device.lockDevice).not.toHaveBeenCalled();
|
|
2133
|
+
expect(deviceWalletSessionStore.get('device-1', 'hidden-state')).toBe('renewed-session');
|
|
2134
|
+
});
|
|
2135
|
+
|
|
2083
2136
|
test('selects the expected hidden wallet when Protocol V2 has no cached session', async () => {
|
|
2084
2137
|
const typedCall = jest
|
|
2085
2138
|
.fn()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logBlockEvent.d.ts","sourceRoot":"","sources":["../../src/events/logBlockEvent.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,aAAa,EAAE,GAAG,CAAC,MAAM,CAKpC,CAAC;
|
|
1
|
+
{"version":3,"file":"logBlockEvent.d.ts","sourceRoot":"","sources":["../../src/events/logBlockEvent.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,aAAa,EAAE,GAAG,CAAC,MAAM,CAKpC,CAAC;AAYH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAmBrE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAK9E;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAE/E"}
|
package/dist/index.js
CHANGED
|
@@ -41663,61 +41663,13 @@ const LogBlockEvent = new Set([
|
|
|
41663
41663
|
UI_RESPONSE.RECEIVE_PIN,
|
|
41664
41664
|
UI_RESPONSE.RECEIVE_PASSPHRASE,
|
|
41665
41665
|
]);
|
|
41666
|
-
const
|
|
41667
|
-
'openWalletSession',
|
|
41666
|
+
const LogPayloadBlockMethod = new Set([
|
|
41668
41667
|
'deviceUploadNft',
|
|
41669
41668
|
'deviceUploadWallpaper',
|
|
41670
41669
|
'uploadPortfolio',
|
|
41671
41670
|
'fileWrite',
|
|
41672
41671
|
'fileRead',
|
|
41673
41672
|
]);
|
|
41674
|
-
const LogPayloadBlockMethod = new Set([
|
|
41675
|
-
'deviceUploadNft',
|
|
41676
|
-
'deviceUploadWallpaper',
|
|
41677
|
-
'uploadPortfolio',
|
|
41678
|
-
]);
|
|
41679
|
-
const SensitiveLogKeys = new Set([
|
|
41680
|
-
'devicestate',
|
|
41681
|
-
'entropy',
|
|
41682
|
-
'expectedpassphrasestate',
|
|
41683
|
-
'mnemonic',
|
|
41684
|
-
'passphrase',
|
|
41685
|
-
'passphrasestate',
|
|
41686
|
-
'password',
|
|
41687
|
-
'pin',
|
|
41688
|
-
'privatekey',
|
|
41689
|
-
'seed',
|
|
41690
|
-
'session',
|
|
41691
|
-
'sessionid',
|
|
41692
|
-
'walletsessionid',
|
|
41693
|
-
'xprv',
|
|
41694
|
-
]);
|
|
41695
|
-
const normalizeLogKey = (key) => key.replace(/[_-]/g, '').toLowerCase();
|
|
41696
|
-
const isSigningMethod = (methodName) => /sign/i.test(methodName);
|
|
41697
|
-
const redactLogValue = (value, seen) => {
|
|
41698
|
-
if (ArrayBuffer.isView(value)) {
|
|
41699
|
-
return `[BINARY:${value.byteLength}]`;
|
|
41700
|
-
}
|
|
41701
|
-
if (value instanceof ArrayBuffer) {
|
|
41702
|
-
return `[BINARY:${value.byteLength}]`;
|
|
41703
|
-
}
|
|
41704
|
-
if (Array.isArray(value)) {
|
|
41705
|
-
return value.map(item => redactLogValue(item, seen));
|
|
41706
|
-
}
|
|
41707
|
-
if (!value || typeof value !== 'object')
|
|
41708
|
-
return value;
|
|
41709
|
-
if (seen.has(value))
|
|
41710
|
-
return '[CIRCULAR]';
|
|
41711
|
-
seen.add(value);
|
|
41712
|
-
const redacted = Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
41713
|
-
key,
|
|
41714
|
-
SensitiveLogKeys.has(normalizeLogKey(key)) && item !== null && item !== undefined
|
|
41715
|
-
? '[REDACTED]'
|
|
41716
|
-
: redactLogValue(item, seen),
|
|
41717
|
-
]));
|
|
41718
|
-
seen.delete(value);
|
|
41719
|
-
return redacted;
|
|
41720
|
-
};
|
|
41721
41673
|
function getLogBlockLabel(message) {
|
|
41722
41674
|
if (!message || typeof message !== 'object')
|
|
41723
41675
|
return undefined;
|
|
@@ -41726,26 +41678,16 @@ function getLogBlockLabel(message) {
|
|
|
41726
41678
|
return type;
|
|
41727
41679
|
}
|
|
41728
41680
|
const methodName = method !== null && method !== void 0 ? method : payload === null || payload === void 0 ? void 0 : payload.method;
|
|
41729
|
-
if (methodName &&
|
|
41681
|
+
if (methodName && LogPayloadBlockMethod.has(methodName)) {
|
|
41730
41682
|
return methodName;
|
|
41731
41683
|
}
|
|
41732
41684
|
return undefined;
|
|
41733
41685
|
}
|
|
41734
41686
|
function getSafeLogPayload(value, blockLabel) {
|
|
41735
|
-
if (blockLabel
|
|
41736
|
-
(LogBlockEvent.has(blockLabel) ||
|
|
41737
|
-
LogPayloadBlockMethod.has(blockLabel) ||
|
|
41738
|
-
isSigningMethod(blockLabel))) {
|
|
41687
|
+
if (blockLabel) {
|
|
41739
41688
|
return { method: blockLabel, payload: '[REDACTED]' };
|
|
41740
41689
|
}
|
|
41741
|
-
|
|
41742
|
-
if (blockLabel &&
|
|
41743
|
-
redactedValue &&
|
|
41744
|
-
typeof redactedValue === 'object' &&
|
|
41745
|
-
!Array.isArray(redactedValue)) {
|
|
41746
|
-
return Object.assign(Object.assign({}, redactedValue), { method: blockLabel });
|
|
41747
|
-
}
|
|
41748
|
-
return redactedValue;
|
|
41690
|
+
return value;
|
|
41749
41691
|
}
|
|
41750
41692
|
function formatLogMethodLabel(label, methodName) {
|
|
41751
41693
|
return methodName ? `${label} [${methodName}]` : label;
|
|
@@ -41869,7 +41811,7 @@ const selectDeviceSession = (device, expectedPassphraseState, deriveCardano, onS
|
|
|
41869
41811
|
return getDeviceSession(device, buildDeviceSessionGetRequest());
|
|
41870
41812
|
});
|
|
41871
41813
|
function getProtocolV2WalletSession(device, options) {
|
|
41872
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
41814
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
41873
41815
|
return __awaiter(this, void 0, void 0, function* () {
|
|
41874
41816
|
const forceWalletSelection = (options === null || options === void 0 ? void 0 : options.forceWalletSelection) === true || (options === null || options === void 0 ? void 0 : options.initSession) === true;
|
|
41875
41817
|
const readCurrentAttachPinSession = (options === null || options === void 0 ? void 0 : options.readCurrentAttachPinSession) === true;
|
|
@@ -41940,7 +41882,7 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
41940
41882
|
return keepAttachPin ? Object.assign(session, { viaAttachPin: true }) : session;
|
|
41941
41883
|
});
|
|
41942
41884
|
const rejectMismatchedAttachPinWallet = () => __awaiter(this, void 0, void 0, function* () {
|
|
41943
|
-
var
|
|
41885
|
+
var _o;
|
|
41944
41886
|
const features = yield refreshProtocolV2DeviceStatus(device);
|
|
41945
41887
|
markWalletStatusRefreshed();
|
|
41946
41888
|
if (features.unlockedAttachPin !== true) {
|
|
@@ -41949,10 +41891,10 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
41949
41891
|
try {
|
|
41950
41892
|
yield device.lockDevice();
|
|
41951
41893
|
}
|
|
41952
|
-
catch (
|
|
41894
|
+
catch (_p) {
|
|
41953
41895
|
}
|
|
41954
41896
|
if (options === null || options === void 0 ? void 0 : options.rejectAttachPinForMainWallet) {
|
|
41955
|
-
(
|
|
41897
|
+
(_o = device.clearStandardInternalState) === null || _o === void 0 ? void 0 : _o.call(device);
|
|
41956
41898
|
device.clearInternalState();
|
|
41957
41899
|
}
|
|
41958
41900
|
else {
|
|
@@ -41961,11 +41903,11 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
41961
41903
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckUnlockTypeError);
|
|
41962
41904
|
});
|
|
41963
41905
|
const lockAttachPinBeforePassphraseSelection = () => __awaiter(this, void 0, void 0, function* () {
|
|
41964
|
-
var
|
|
41906
|
+
var _q;
|
|
41965
41907
|
if (readCurrentAttachPinSession || (options === null || options === void 0 ? void 0 : options.onlyMainPin)) {
|
|
41966
41908
|
return;
|
|
41967
41909
|
}
|
|
41968
|
-
if (((
|
|
41910
|
+
if (((_q = device.features) === null || _q === void 0 ? void 0 : _q.unlockedAttachPin) !== true) {
|
|
41969
41911
|
return;
|
|
41970
41912
|
}
|
|
41971
41913
|
yield rejectMismatchedAttachPinWallet();
|
|
@@ -41986,8 +41928,8 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
41986
41928
|
}
|
|
41987
41929
|
});
|
|
41988
41930
|
const selectStandardWallet = (forceMainPin = false) => __awaiter(this, void 0, void 0, function* () {
|
|
41989
|
-
var
|
|
41990
|
-
if (((
|
|
41931
|
+
var _r;
|
|
41932
|
+
if (((_r = device.features) === null || _r === void 0 ? void 0 : _r.passphraseProtection) === true) {
|
|
41991
41933
|
yield selectMainPin();
|
|
41992
41934
|
yield askDevicePassphrase(device, {
|
|
41993
41935
|
passphrase: '',
|
|
@@ -42052,6 +41994,9 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
42052
41994
|
throw error;
|
|
42053
41995
|
}
|
|
42054
41996
|
resumed = false;
|
|
41997
|
+
if (((_g = device.features) === null || _g === void 0 ? void 0 : _g.unlockedAttachPin) === true) {
|
|
41998
|
+
response = yield getDeviceSession(device, sessionGetRequest());
|
|
41999
|
+
}
|
|
42055
42000
|
}
|
|
42056
42001
|
}
|
|
42057
42002
|
else if (expectedPassphraseState) {
|
|
@@ -42080,7 +42025,7 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
42080
42025
|
}
|
|
42081
42026
|
catch (error) {
|
|
42082
42027
|
if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
|
|
42083
|
-
(
|
|
42028
|
+
(_h = device.clearStandardInternalState) === null || _h === void 0 ? void 0 : _h.call(device);
|
|
42084
42029
|
}
|
|
42085
42030
|
else {
|
|
42086
42031
|
device.clearInternalState();
|
|
@@ -42095,7 +42040,7 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
42095
42040
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WalletSessionInvalid);
|
|
42096
42041
|
}
|
|
42097
42042
|
if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
|
|
42098
|
-
(
|
|
42043
|
+
(_j = device.clearStandardInternalState) === null || _j === void 0 ? void 0 : _j.call(device);
|
|
42099
42044
|
yield selectStandardWallet(true);
|
|
42100
42045
|
response = yield getDeviceSession(device, sessionGetRequest());
|
|
42101
42046
|
}
|
|
@@ -42110,7 +42055,7 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
42110
42055
|
}
|
|
42111
42056
|
catch (error) {
|
|
42112
42057
|
if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
|
|
42113
|
-
(
|
|
42058
|
+
(_k = device.clearStandardInternalState) === null || _k === void 0 ? void 0 : _k.call(device);
|
|
42114
42059
|
}
|
|
42115
42060
|
else {
|
|
42116
42061
|
device.clearInternalState();
|
|
@@ -42133,7 +42078,7 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
42133
42078
|
if (sessionIsAttachPinWallet(response)) {
|
|
42134
42079
|
response = yield askEmptyPassphraseAndGet({ deriveCardano: true, keepAttachPin: true });
|
|
42135
42080
|
}
|
|
42136
|
-
else if (((
|
|
42081
|
+
else if (((_l = device.features) === null || _l === void 0 ? void 0 : _l.passphraseProtection) === false) {
|
|
42137
42082
|
response = yield getDeviceSession(device, buildDeviceSessionGetRequest());
|
|
42138
42083
|
}
|
|
42139
42084
|
else if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
|
|
@@ -42150,7 +42095,7 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
42150
42095
|
}
|
|
42151
42096
|
catch (error) {
|
|
42152
42097
|
if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
|
|
42153
|
-
(
|
|
42098
|
+
(_m = device.clearStandardInternalState) === null || _m === void 0 ? void 0 : _m.call(device);
|
|
42154
42099
|
}
|
|
42155
42100
|
else {
|
|
42156
42101
|
device.clearInternalState();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walletSession.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/walletSession.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAuBlD,wBAAsB,6BAA6B,CAAC,MAAM,EAAE,MAAM,0DAGjE;AAED,wBAAsB,6BAA6B,CAAC,MAAM,EAAE,MAAM,qCAGjE;AAED,wBAAsB,qCAAqC,CAAC,MAAM,EAAE,MAAM,oBAgBzE;AA8JD,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;;;;;;
|
|
1
|
+
{"version":3,"file":"walletSession.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/walletSession.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAuBlD,wBAAsB,6BAA6B,CAAC,MAAM,EAAE,MAAM,0DAGjE;AAED,wBAAsB,6BAA6B,CAAC,MAAM,EAAE,MAAM,qCAGjE;AAED,wBAAsB,qCAAqC,CAAC,MAAM,EAAE,MAAM,oBAgBzE;AA8JD,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;;;;;;GAkYF;AAED,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,MAAM,EACd,uBAAuB,EAAE,MAAM,EAC/B,aAAa,CAAC,EAAE,OAAO;;;;;;GAOxB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.2.2-alpha.
|
|
3
|
+
"version": "1.2.2-alpha.11",
|
|
4
4
|
"description": "Core processes and APIs for communicating with OneKey hardware devices.",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@onekeyfe/hd-shared": "1.2.2-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.2.2-alpha.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.2.2-alpha.11",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.2-alpha.11",
|
|
30
30
|
"axios": "1.15.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
32
|
"buffer": "^6.0.3",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"@types/w3c-web-usb": "^1.0.10",
|
|
47
47
|
"@types/web-bluetooth": "^0.0.21"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "8928100acb893d72361eb74422d5e2a0f7af77d8"
|
|
50
50
|
}
|
|
@@ -8,8 +8,9 @@ export const LogBlockEvent: Set<string> = new Set([
|
|
|
8
8
|
UI_RESPONSE.RECEIVE_PASSPHRASE,
|
|
9
9
|
]);
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
// These resource/file APIs did not exist in 1.1.32. Skip the payload so
|
|
12
|
+
// the log layer does not copy huge Base64 or binary data.
|
|
13
|
+
const LogPayloadBlockMethod: Set<string> = new Set([
|
|
13
14
|
'deviceUploadNft',
|
|
14
15
|
'deviceUploadWallpaper',
|
|
15
16
|
'uploadPortfolio',
|
|
@@ -17,61 +18,6 @@ const LogLabelMethod: Set<string> = new Set([
|
|
|
17
18
|
'fileRead',
|
|
18
19
|
]);
|
|
19
20
|
|
|
20
|
-
// 资源上传参数可能包含很大的 Base64 字符串。这里按方法整段跳过,避免日志层
|
|
21
|
-
// 递归复制和序列化这些数据;资源 API 与传输内容本身保持不变。
|
|
22
|
-
const LogPayloadBlockMethod: Set<string> = new Set([
|
|
23
|
-
'deviceUploadNft',
|
|
24
|
-
'deviceUploadWallpaper',
|
|
25
|
-
'uploadPortfolio',
|
|
26
|
-
]);
|
|
27
|
-
|
|
28
|
-
const SensitiveLogKeys: Set<string> = new Set([
|
|
29
|
-
'devicestate',
|
|
30
|
-
'entropy',
|
|
31
|
-
'expectedpassphrasestate',
|
|
32
|
-
'mnemonic',
|
|
33
|
-
'passphrase',
|
|
34
|
-
'passphrasestate',
|
|
35
|
-
'password',
|
|
36
|
-
'pin',
|
|
37
|
-
'privatekey',
|
|
38
|
-
'seed',
|
|
39
|
-
'session',
|
|
40
|
-
'sessionid',
|
|
41
|
-
'walletsessionid',
|
|
42
|
-
'xprv',
|
|
43
|
-
]);
|
|
44
|
-
|
|
45
|
-
const normalizeLogKey = (key: string) => key.replace(/[_-]/g, '').toLowerCase();
|
|
46
|
-
|
|
47
|
-
const isSigningMethod = (methodName: string) => /sign/i.test(methodName);
|
|
48
|
-
|
|
49
|
-
const redactLogValue = (value: unknown, seen: WeakSet<object>): unknown => {
|
|
50
|
-
if (ArrayBuffer.isView(value)) {
|
|
51
|
-
return `[BINARY:${value.byteLength}]`;
|
|
52
|
-
}
|
|
53
|
-
if (value instanceof ArrayBuffer) {
|
|
54
|
-
return `[BINARY:${value.byteLength}]`;
|
|
55
|
-
}
|
|
56
|
-
if (Array.isArray(value)) {
|
|
57
|
-
return value.map(item => redactLogValue(item, seen));
|
|
58
|
-
}
|
|
59
|
-
if (!value || typeof value !== 'object') return value;
|
|
60
|
-
if (seen.has(value)) return '[CIRCULAR]';
|
|
61
|
-
|
|
62
|
-
seen.add(value);
|
|
63
|
-
const redacted = Object.fromEntries(
|
|
64
|
-
Object.entries(value as Record<string, unknown>).map(([key, item]) => [
|
|
65
|
-
key,
|
|
66
|
-
SensitiveLogKeys.has(normalizeLogKey(key)) && item !== null && item !== undefined
|
|
67
|
-
? '[REDACTED]'
|
|
68
|
-
: redactLogValue(item, seen),
|
|
69
|
-
])
|
|
70
|
-
);
|
|
71
|
-
seen.delete(value);
|
|
72
|
-
return redacted;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
21
|
export function getLogBlockLabel(message: unknown): string | undefined {
|
|
76
22
|
if (!message || typeof message !== 'object') return undefined;
|
|
77
23
|
|
|
@@ -86,7 +32,7 @@ export function getLogBlockLabel(message: unknown): string | undefined {
|
|
|
86
32
|
}
|
|
87
33
|
|
|
88
34
|
const methodName = method ?? payload?.method;
|
|
89
|
-
if (methodName &&
|
|
35
|
+
if (methodName && LogPayloadBlockMethod.has(methodName)) {
|
|
90
36
|
return methodName;
|
|
91
37
|
}
|
|
92
38
|
|
|
@@ -94,25 +40,10 @@ export function getLogBlockLabel(message: unknown): string | undefined {
|
|
|
94
40
|
}
|
|
95
41
|
|
|
96
42
|
export function getSafeLogPayload(value: unknown, blockLabel?: string): unknown {
|
|
97
|
-
if (
|
|
98
|
-
blockLabel &&
|
|
99
|
-
(LogBlockEvent.has(blockLabel) ||
|
|
100
|
-
LogPayloadBlockMethod.has(blockLabel) ||
|
|
101
|
-
isSigningMethod(blockLabel))
|
|
102
|
-
) {
|
|
43
|
+
if (blockLabel) {
|
|
103
44
|
return { method: blockLabel, payload: '[REDACTED]' };
|
|
104
45
|
}
|
|
105
|
-
|
|
106
|
-
const redactedValue = redactLogValue(value, new WeakSet());
|
|
107
|
-
if (
|
|
108
|
-
blockLabel &&
|
|
109
|
-
redactedValue &&
|
|
110
|
-
typeof redactedValue === 'object' &&
|
|
111
|
-
!Array.isArray(redactedValue)
|
|
112
|
-
) {
|
|
113
|
-
return { ...redactedValue, method: blockLabel };
|
|
114
|
-
}
|
|
115
|
-
return redactedValue;
|
|
46
|
+
return value;
|
|
116
47
|
}
|
|
117
48
|
|
|
118
49
|
export function formatLogMethodLabel(label: string, methodName?: string): string {
|
|
@@ -234,9 +234,9 @@ export async function getProtocolV2WalletSession(
|
|
|
234
234
|
const forceWalletSelection =
|
|
235
235
|
options?.forceWalletSelection === true || options?.initSession === true;
|
|
236
236
|
const readCurrentAttachPinSession = options?.readCurrentAttachPinSession === true;
|
|
237
|
-
const sessionIsAttachPinWallet = (session?:
|
|
237
|
+
const sessionIsAttachPinWallet = (session?: unknown) =>
|
|
238
238
|
readCurrentAttachPinSession ||
|
|
239
|
-
session?.viaAttachPin === true ||
|
|
239
|
+
(session as { viaAttachPin?: boolean } | undefined)?.viaAttachPin === true ||
|
|
240
240
|
device.features?.unlockedAttachPin === true;
|
|
241
241
|
|
|
242
242
|
if (forceWalletSelection) {
|
|
@@ -455,6 +455,11 @@ export async function getProtocolV2WalletSession(
|
|
|
455
455
|
throw error;
|
|
456
456
|
}
|
|
457
457
|
resumed = false;
|
|
458
|
+
if (device.features?.unlockedAttachPin === true) {
|
|
459
|
+
// Locking invalidates the old handle, but Attach PIN already selected the wallet.
|
|
460
|
+
// Read the current session and validate its passphrase state below.
|
|
461
|
+
response = await getDeviceSession(device, sessionGetRequest());
|
|
462
|
+
}
|
|
458
463
|
}
|
|
459
464
|
} else if (expectedPassphraseState) {
|
|
460
465
|
try {
|