@onekeyfe/hd-core 1.2.0-alpha.89 → 1.2.0-alpha.90
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__/check-all-firmware-release-protocol-v2.test.ts +5 -3
- package/__tests__/firmware-update/device-update-bootloader.test.ts +2 -1
- package/__tests__/firmware-update/firmware-prepared-host-digest.test.ts +209 -0
- package/__tests__/firmware-update/firmware-update-plan.test.ts +69 -0
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -1
- package/dist/index.js +30 -24
- package/package.json +4 -4
- package/src/api/CheckAllFirmwareRelease.ts +8 -13
- package/src/api/FirmwareUpdateV2.ts +8 -3
- package/src/api/FirmwareUpdateV3.ts +11 -4
- package/src/api/device/DeviceUpdateBootloader.ts +11 -4
- package/src/api/firmware/FirmwareUpdatePlan.ts +7 -11
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +2 -2
|
@@ -453,7 +453,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
453
453
|
});
|
|
454
454
|
});
|
|
455
455
|
|
|
456
|
-
test('
|
|
456
|
+
test('builds a Desktop V4 prepared update without device identity', async () => {
|
|
457
457
|
const currentRelease: IFirmwareReleaseInfo = {
|
|
458
458
|
...release,
|
|
459
459
|
required: false,
|
|
@@ -490,8 +490,10 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
490
490
|
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
491
491
|
|
|
492
492
|
await expect(method.run()).resolves.toMatchObject({
|
|
493
|
-
|
|
494
|
-
|
|
493
|
+
firmwareUpdatePlan: {
|
|
494
|
+
executor: 'v4',
|
|
495
|
+
deviceIdentity: 'unavailable',
|
|
496
|
+
},
|
|
495
497
|
});
|
|
496
498
|
});
|
|
497
499
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
jest.mock('../../src/api/firmware/FirmwareUpdatePreparedPlan', () => ({
|
|
10
10
|
assertFirmwareUpdatePreparedPlanBinding: jest.fn(),
|
|
11
11
|
assertFirmwareUpdatePreparedPlanDeviceIdentity: jest.fn(),
|
|
12
|
+
validateFirmwareUpdatePreparedPlan: jest.fn((preparedPlan: unknown) => preparedPlan),
|
|
12
13
|
}));
|
|
13
14
|
|
|
14
15
|
jest.mock('../../src/data-manager', () => ({
|
|
@@ -46,7 +47,7 @@ const createMethod = () => {
|
|
|
46
47
|
method: 'deviceUpdateBootloader',
|
|
47
48
|
artifact,
|
|
48
49
|
hostBindingGeneration,
|
|
49
|
-
preparedPlan: {},
|
|
50
|
+
preparedPlan: { preparedPlanDigest: 'a'.repeat(64) },
|
|
50
51
|
},
|
|
51
52
|
});
|
|
52
53
|
(method as any).device = {
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { EDeviceType, EFirmwareType } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
import FirmwareUpdateV2 from '../../src/api/FirmwareUpdateV2';
|
|
4
|
+
import FirmwareUpdateV3 from '../../src/api/FirmwareUpdateV3';
|
|
5
|
+
import DeviceUpdateBootloader from '../../src/api/device/DeviceUpdateBootloader';
|
|
6
|
+
import {
|
|
7
|
+
registerFirmwareUpdateHostBinding,
|
|
8
|
+
unregisterFirmwareUpdateHostBinding,
|
|
9
|
+
} from '../../src/api/firmware/FirmwareHostBinding';
|
|
10
|
+
import { prepareFirmwareUpdatePlan } from '../../src/api/firmware/FirmwareUpdatePreparedPlan';
|
|
11
|
+
import { buildFirmwareUpdatePlan } from '../../src/api/firmware/FirmwareUpdatePlan';
|
|
12
|
+
|
|
13
|
+
import type { FirmwareArtifactReference } from '../../src/types/api/firmwareUpdate';
|
|
14
|
+
import type { Features } from '../../src/types';
|
|
15
|
+
|
|
16
|
+
jest.mock('../../src/data/config', () => ({
|
|
17
|
+
getSDKVersion: jest.fn(() => '1.0.0'),
|
|
18
|
+
DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0/',
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
const noUpdate = {
|
|
22
|
+
status: 'valid' as const,
|
|
23
|
+
release: undefined,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const createPreparedPlan = ({
|
|
27
|
+
executor,
|
|
28
|
+
target,
|
|
29
|
+
}: {
|
|
30
|
+
executor: 'v2' | 'v3';
|
|
31
|
+
target: 'firmware' | 'bootloader';
|
|
32
|
+
}) => {
|
|
33
|
+
const sha256 = target === 'firmware' ? 'a'.repeat(64) : 'b'.repeat(64);
|
|
34
|
+
const artifact: FirmwareArtifactReference = {
|
|
35
|
+
artifactRef: `fw:${sha256}`,
|
|
36
|
+
size: 4,
|
|
37
|
+
sha256,
|
|
38
|
+
};
|
|
39
|
+
const isV3 = executor === 'v3';
|
|
40
|
+
const plan = buildFirmwareUpdatePlan({
|
|
41
|
+
features: {
|
|
42
|
+
deviceType: isV3 ? EDeviceType.Pro : EDeviceType.Classic1s,
|
|
43
|
+
serialNo: isV3 ? 'pro-device-id' : 'classic-device-id',
|
|
44
|
+
firmwareVersion: '1.0.0',
|
|
45
|
+
bootloaderVersion: isV3 ? '2.8.0' : '1.0.0',
|
|
46
|
+
} as Features,
|
|
47
|
+
firmwareType: EFirmwareType.Universal,
|
|
48
|
+
platform: 'desktop',
|
|
49
|
+
firmware:
|
|
50
|
+
target === 'firmware'
|
|
51
|
+
? {
|
|
52
|
+
status: 'outdated',
|
|
53
|
+
release: {
|
|
54
|
+
url: 'https://firmware.onekey.so/firmware.bin',
|
|
55
|
+
expectedSize: artifact.size,
|
|
56
|
+
fingerprint: artifact.sha256,
|
|
57
|
+
version: [3, 0, 0],
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
: noUpdate,
|
|
61
|
+
ble: noUpdate,
|
|
62
|
+
bootloader:
|
|
63
|
+
target === 'bootloader'
|
|
64
|
+
? {
|
|
65
|
+
status: 'outdated',
|
|
66
|
+
shouldUpdate: true,
|
|
67
|
+
release: {
|
|
68
|
+
bootloaderResource: 'https://firmware.onekey.so/bootloader.bin',
|
|
69
|
+
bootloaderExpectedSize: artifact.size,
|
|
70
|
+
bootloaderFingerprint: artifact.sha256,
|
|
71
|
+
bootloaderVersion: [2, 0, 0],
|
|
72
|
+
},
|
|
73
|
+
}
|
|
74
|
+
: noUpdate,
|
|
75
|
+
});
|
|
76
|
+
expect(plan.executor).toBe(executor);
|
|
77
|
+
const preparedPlan = prepareFirmwareUpdatePlan({
|
|
78
|
+
plan,
|
|
79
|
+
leaseRef: `fwlease:${executor}:${target}`,
|
|
80
|
+
artifacts: [{ artifactId: target, artifact }],
|
|
81
|
+
});
|
|
82
|
+
return { artifact, preparedPlan };
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const registerMismatchedHost = () => {
|
|
86
|
+
const artifactReader = {
|
|
87
|
+
open: jest.fn(),
|
|
88
|
+
read: jest.fn(),
|
|
89
|
+
close: jest.fn(),
|
|
90
|
+
};
|
|
91
|
+
const hostBindingGeneration = registerFirmwareUpdateHostBinding({
|
|
92
|
+
preparedPlanDigest: 'f'.repeat(64),
|
|
93
|
+
artifactReader,
|
|
94
|
+
});
|
|
95
|
+
return { artifactReader, hostBindingGeneration };
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
describe('prepared firmware host digest binding', () => {
|
|
99
|
+
afterEach(() => {
|
|
100
|
+
unregisterFirmwareUpdateHostBinding();
|
|
101
|
+
jest.restoreAllMocks();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('FirmwareUpdateV2 rejects a host registered for another prepared plan', () => {
|
|
105
|
+
const { artifact, preparedPlan } = createPreparedPlan({
|
|
106
|
+
executor: 'v2',
|
|
107
|
+
target: 'firmware',
|
|
108
|
+
});
|
|
109
|
+
const { artifactReader, hostBindingGeneration } = registerMismatchedHost();
|
|
110
|
+
const method = new FirmwareUpdateV2({
|
|
111
|
+
id: 1,
|
|
112
|
+
payload: {
|
|
113
|
+
method: 'firmwareUpdateV2',
|
|
114
|
+
platform: 'desktop',
|
|
115
|
+
updateType: 'firmware',
|
|
116
|
+
artifact,
|
|
117
|
+
preparedPlan,
|
|
118
|
+
hostBindingGeneration,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
expect(() => method.init()).toThrow('does not match the prepared plan');
|
|
123
|
+
expect(artifactReader.open).not.toHaveBeenCalled();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test('FirmwareUpdateV3 rejects a host registered for another prepared plan', () => {
|
|
127
|
+
const { artifact, preparedPlan } = createPreparedPlan({
|
|
128
|
+
executor: 'v3',
|
|
129
|
+
target: 'firmware',
|
|
130
|
+
});
|
|
131
|
+
const { artifactReader, hostBindingGeneration } = registerMismatchedHost();
|
|
132
|
+
const method = new FirmwareUpdateV3({
|
|
133
|
+
id: 1,
|
|
134
|
+
payload: {
|
|
135
|
+
method: 'firmwareUpdateV3',
|
|
136
|
+
platform: 'desktop',
|
|
137
|
+
artifacts: { firmware: artifact },
|
|
138
|
+
preparedPlan,
|
|
139
|
+
hostBindingGeneration,
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
expect(() => method.init()).toThrow('does not match the prepared plan');
|
|
144
|
+
expect(artifactReader.open).not.toHaveBeenCalled();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test('DeviceUpdateBootloader rejects a host registered for another prepared plan', async () => {
|
|
148
|
+
const { artifact, preparedPlan } = createPreparedPlan({
|
|
149
|
+
executor: 'v2',
|
|
150
|
+
target: 'bootloader',
|
|
151
|
+
});
|
|
152
|
+
const { artifactReader, hostBindingGeneration } = registerMismatchedHost();
|
|
153
|
+
const method = new DeviceUpdateBootloader({
|
|
154
|
+
id: 1,
|
|
155
|
+
payload: {
|
|
156
|
+
method: 'deviceUpdateBootloader',
|
|
157
|
+
artifact,
|
|
158
|
+
preparedPlan,
|
|
159
|
+
hostBindingGeneration,
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
method.device = {
|
|
163
|
+
features: {
|
|
164
|
+
deviceType: EDeviceType.Classic1s,
|
|
165
|
+
serialNo: 'classic-device-id',
|
|
166
|
+
},
|
|
167
|
+
} as any;
|
|
168
|
+
|
|
169
|
+
await expect(method.run()).rejects.toThrow('does not match the prepared plan');
|
|
170
|
+
expect(artifactReader.open).not.toHaveBeenCalled();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test('keeps non-prepared direct binary calls on the legacy paths', async () => {
|
|
174
|
+
const v2 = new FirmwareUpdateV2({
|
|
175
|
+
id: 1,
|
|
176
|
+
payload: {
|
|
177
|
+
method: 'firmwareUpdateV2',
|
|
178
|
+
platform: 'desktop',
|
|
179
|
+
updateType: 'firmware',
|
|
180
|
+
binary: new ArrayBuffer(4),
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
const v3 = new FirmwareUpdateV3({
|
|
184
|
+
id: 2,
|
|
185
|
+
payload: {
|
|
186
|
+
method: 'firmwareUpdateV3',
|
|
187
|
+
platform: 'desktop',
|
|
188
|
+
firmwareBinary: new ArrayBuffer(4),
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
const bootloader = new DeviceUpdateBootloader({
|
|
192
|
+
id: 3,
|
|
193
|
+
payload: {
|
|
194
|
+
method: 'deviceUpdateBootloader',
|
|
195
|
+
binary: new ArrayBuffer(4),
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
bootloader.device = {
|
|
199
|
+
features: {},
|
|
200
|
+
getCurrentDeviceType: () => EDeviceType.Touch,
|
|
201
|
+
getCurrentFirmwareType: () => EFirmwareType.Universal,
|
|
202
|
+
} as any;
|
|
203
|
+
jest.spyOn(bootloader, 'updateTouchBootloader').mockResolvedValue(true);
|
|
204
|
+
|
|
205
|
+
expect(() => v2.init()).not.toThrow();
|
|
206
|
+
expect(() => v3.init()).not.toThrow();
|
|
207
|
+
await expect(bootloader.run()).resolves.toBe(true);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { EDeviceType, EFirmwareType } from '@onekeyfe/hd-shared';
|
|
2
2
|
|
|
3
3
|
import { buildFirmwareUpdatePlan } from '../../src/api/firmware/FirmwareUpdatePlan';
|
|
4
|
+
import {
|
|
5
|
+
assertFirmwareUpdatePreparedPlanDeviceIdentity,
|
|
6
|
+
prepareFirmwareUpdatePlan,
|
|
7
|
+
} from '../../src/api/firmware/FirmwareUpdatePreparedPlan';
|
|
4
8
|
|
|
5
9
|
import type { Features } from '../../src/types';
|
|
6
10
|
|
|
@@ -362,6 +366,71 @@ describe('buildFirmwareUpdatePlan', () => {
|
|
|
362
366
|
).toThrow('requires a stable device identity');
|
|
363
367
|
});
|
|
364
368
|
|
|
369
|
+
test('allows an identity-less Protocol V2 device while retaining the model binding', () => {
|
|
370
|
+
const features = createFeatures({
|
|
371
|
+
deviceType: EDeviceType.Pro2,
|
|
372
|
+
});
|
|
373
|
+
delete (features as Partial<Features>).serialNo;
|
|
374
|
+
|
|
375
|
+
const plan = buildFirmwareUpdatePlan({
|
|
376
|
+
features,
|
|
377
|
+
firmwareType: EFirmwareType.Universal,
|
|
378
|
+
platform: 'desktop',
|
|
379
|
+
firmware: {
|
|
380
|
+
status: 'outdated',
|
|
381
|
+
release: {
|
|
382
|
+
components: {
|
|
383
|
+
applicationP1: {
|
|
384
|
+
target: 'APPLICATION_P1',
|
|
385
|
+
url: 'https://firmware.onekey.so/pro2/application-p1.bin',
|
|
386
|
+
expectedSize: 1024,
|
|
387
|
+
fingerprint: '1111111111111111111111111111111111111111111111111111111111111111',
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
ble: noUpdate,
|
|
393
|
+
bootloader: noUpdate,
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
expect(plan).toMatchObject({
|
|
397
|
+
executor: 'v4',
|
|
398
|
+
deviceIdentity: 'unavailable',
|
|
399
|
+
deviceModel: String(EDeviceType.Pro2),
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
const preparedPlan = prepareFirmwareUpdatePlan({
|
|
403
|
+
plan,
|
|
404
|
+
leaseRef: 'fwlease:00000000-0000-4000-8000-000000000004',
|
|
405
|
+
artifacts: [
|
|
406
|
+
{
|
|
407
|
+
artifactId: 'component:app_v1',
|
|
408
|
+
artifact: {
|
|
409
|
+
artifactRef: `fw:${'1'.repeat(64)}`,
|
|
410
|
+
size: 1024,
|
|
411
|
+
sha256: '1'.repeat(64),
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
});
|
|
416
|
+
expect(() =>
|
|
417
|
+
assertFirmwareUpdatePreparedPlanDeviceIdentity({
|
|
418
|
+
preparedPlan,
|
|
419
|
+
deviceIdentity: undefined,
|
|
420
|
+
bootloaderMode: false,
|
|
421
|
+
deviceModel: String(EDeviceType.Pro2),
|
|
422
|
+
})
|
|
423
|
+
).not.toThrow();
|
|
424
|
+
expect(() =>
|
|
425
|
+
assertFirmwareUpdatePreparedPlanDeviceIdentity({
|
|
426
|
+
preparedPlan,
|
|
427
|
+
deviceIdentity: undefined,
|
|
428
|
+
bootloaderMode: false,
|
|
429
|
+
deviceModel: String(EDeviceType.Neo),
|
|
430
|
+
})
|
|
431
|
+
).toThrow();
|
|
432
|
+
});
|
|
433
|
+
|
|
365
434
|
test('maps the Pro2 component order without downloading artifacts', () => {
|
|
366
435
|
const plan = buildFirmwareUpdatePlan({
|
|
367
436
|
features: createFeatures({ deviceType: EDeviceType.Pro2 }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckAllFirmwareRelease.d.ts","sourceRoot":"","sources":["../../src/api/CheckAllFirmwareRelease.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"CheckAllFirmwareRelease.d.ts","sourceRoot":"","sources":["../../src/api/CheckAllFirmwareRelease.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAgC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EACV,kBAAkB,EAElB,kCAAkC,EAClC,+BAA+B,EAChC,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAGrB,MAAM,UAAU,CAAC;AAgIlB,MAAM,MAAM,6BAA6B,GAAG;IAC1C,YAAY,EAAE,aAAa,CAAC;IAC5B,MAAM,EAAE,+BAA+B,CAAC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,mBAAmB,CAAC;IACrC,UAAU,EAAE,kCAAkC,EAAE,CAAC;IACjD,eAAe,EAAE,sBAAsB,EAAE,CAAC;IAC1C,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,EAC7C,eAAe,EACf,mBAAwB,EACxB,iBAAyB,EACzB,mBAAwB,EACxB,YAAY,EACZ,OAAO,EACP,UAAU,GACX,EAAE;IACD,eAAe,EAAE,mBAAmB,CAAC;IACrC,mBAAmB,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACpD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mBAAmB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9D,YAAY,EAAE,aAAa,CAAC;IAC5B,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC7B,GAAG,6BAA6B,CAiFhC;AAID,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,UAAU;IAC7D,qBAAqB;IAIrB,IAAI;IAME,GAAG;YAuFK,aAAa;CAsH5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwareUpdateV2.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV2.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EAEb,KAAK,aAAa,EAKnB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"FirmwareUpdateV2.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV2.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EAEb,KAAK,aAAa,EAKnB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA0B1C,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,UAAU,CAAC;AAEtD,OAAO,KAAK,EACV,sBAAsB,EACtB,yBAAyB,EAC1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC;AAE1F,KAAK,MAAM,GAAG;IACZ,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IACrC,eAAe,CAAC,EAAE,KAAK,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,yBAAyB,CAAC;KACrC,CAAC,CAAC;IACH,cAAc,CAAC,EAAE,sBAAsB,CAAC;IACxC,YAAY,CAAC,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,EAAE,0BAA0B,CAAC,UAAU,CAAC,CAAC;IAClD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,UAAU,GAAG,KAAK,CAAC;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,aAAa,CAAC;CAC9B,CAAC;AAkFF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,UAAU,CAAC,MAAM,CAAC;IAC9D,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAE1C,IAAI;IAuFJ,cAAc,YAAa,MAAM,UAS/B;YAEY,qCAAqC;IAkBnD,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS;YA8FvC,4BAA4B;IAyB1C,qBAAqB;IAUrB,uBAAuB,CAAC,UAAU,EAAE,MAAM;IAc1C,gCAAgC,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAAE,YAAY,EAAE,aAAa;IAwBtF,GAAG;CAgQV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwareUpdateV3.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV3.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"FirmwareUpdateV3.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV3.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAa/E,OAAO,KAAK,EAEV,sBAAsB,EACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,qBAAqB,CAAC;AAMnE,eAAO,MAAM,gCAAgC,UAAU,CAAC;AAaxD,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,wBAAwB,CAAC,sBAAsB,CAAC;IAC5F,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAE1C,OAAO,CAAC,gBAAgB,CAAS;IAEjC,OAAO,CAAC,eAAe,CAA4B;IAEnD,IAAI;IAyFE,GAAG;;;;;YAQK,aAAa;IA6D3B,OAAO,CAAC,wBAAwB;YAiBlB,kBAAkB;YAelB,oBAAoB;IAKlC,OAAO,CAAC,wBAAwB;YAgBlB,oBAAoB;YA2DpB,uBAAuB;YAuBvB,4BAA4B;YA+E5B,aAAa;IAyN3B,OAAO,CAAC,yBAAyB;IAajC,OAAO,CAAC,yBAAyB;IAQjC,OAAO,CAAC,qBAAqB;IAmB7B,OAAO,CAAC,sCAAsC;IAexC,sBAAsB,CAAC,OAAO,EAAE,MAAM;CA+E7C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceUpdateBootloader.d.ts","sourceRoot":"","sources":["../../../src/api/device/DeviceUpdateBootloader.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"DeviceUpdateBootloader.d.ts","sourceRoot":"","sources":["../../../src/api/device/DeviceUpdateBootloader.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAiBhF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E,MAAM,CAAC,OAAO,OAAO,sBAAuB,SAAQ,wBAAwB,CAAC,GAAG,CAAC;IAC/E,IAAI;IAOE,iCAAiC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW;IAoBtE,2CAA2C,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB;IAcvF,qBAAqB,CAAC,EAC1B,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,cAAc,GACvB,EAAE;QACD,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,YAAY,EAAE,aAAa,CAAC;QAC5B,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,MAAM,CAAC,EAAE,kBAAkB,CAAC;KAC7B;IA0EK,GAAG;CAgFV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwareUpdatePlan.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwareUpdatePlan.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,aAAa,EAA6B,MAAM,qBAAqB,CAAC;AAU5F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,KAAK,EACV,kBAAkB,EAElB,6BAA6B,EAC7B,wBAAwB,EACzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAEvE,KAAK,sBAAsB,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,WAAW,CAAC;AAEjF,KAAK,aAAa,GAAG;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AA+GF,eAAO,MAAM,4BAA4B,UAAW,OAAO,KAAG,MAG3D,CAAC;AAkBJ,eAAO,MAAM,sCAAsC,UAC1C,OAAO,KACb,6BAA6B,EAa/B,CAAC;AAEF,eAAO,MAAM,uCAAuC,UAC3C,OAAO,KACb,sBAAsB,EAaxB,CAAC;AAuBF,eAAO,MAAM,4BAA4B,+BAavC,CAAC;AAEH,eAAO,MAAM,0BAA0B,aAOrC,CAAC;AAYH,eAAO,MAAM,wBAAwB,UAAW,OAAO,KAAG,
|
|
1
|
+
{"version":3,"file":"FirmwareUpdatePlan.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwareUpdatePlan.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,aAAa,EAA6B,MAAM,qBAAqB,CAAC;AAU5F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,KAAK,EACV,kBAAkB,EAElB,6BAA6B,EAC7B,wBAAwB,EACzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAEvE,KAAK,sBAAsB,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,WAAW,CAAC;AAEjF,KAAK,aAAa,GAAG;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AA+GF,eAAO,MAAM,4BAA4B,UAAW,OAAO,KAAG,MAG3D,CAAC;AAkBJ,eAAO,MAAM,sCAAsC,UAC1C,OAAO,KACb,6BAA6B,EAa/B,CAAC;AAEF,eAAO,MAAM,uCAAuC,UAC3C,OAAO,KACb,sBAAsB,EAaxB,CAAC;AAuBF,eAAO,MAAM,4BAA4B,+BAavC,CAAC;AAEH,eAAO,MAAM,0BAA0B,aAOrC,CAAC;AAYH,eAAO,MAAM,wBAAwB,UAAW,OAAO,KAAG,kBAuHzD,CAAC;AAqPF,MAAM,MAAM,yCAAyC,GAAG;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC,sBAAsB,EAAE,gBAAgB,CAAC,CAAC;IAC1D,SAAS,EAAE,KAAK,GAAG,KAAK,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,sCAAsC;cAMvC,QAAQ;kBACJ,aAAa;cACjB,sBAAsB;eACrB,yCAAyC,EAAE;MACpD,kBAmBH,CAAC;AAEF,eAAO,MAAM,iCAAiC;cASlC,QAAQ;kBACJ,aAAa;cACjB,sBAAsB;aACvB,aAAa,GAAG,SAAS;qBACjB,SAAS,sBAAsB,EAAE;;qBAEjC,yBAAyB,GAAG,SAAS;MACpD,kBAgEH,CAAC;AAEF,eAAO,MAAM,uBAAuB;cASxB,QAAQ;kBACJ,aAAa;cACjB,sBAAsB;cACtB,gBAAgB;SACrB,gBAAgB;;;MAGnB,kBAwIH,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -754,7 +754,7 @@ const assertFirmwareUpdatePlan = (value) => {
|
|
|
754
754
|
plan.targetsToUpdate.some(target => legacyOnlyTargets.has(target))) ||
|
|
755
755
|
(plan.artifacts.length > 0 &&
|
|
756
756
|
(plan.platform === 'native' || plan.platform === 'desktop') &&
|
|
757
|
-
plan.executor
|
|
757
|
+
plan.executor === 'v3' &&
|
|
758
758
|
plan.deviceIdentity === 'unavailable')) {
|
|
759
759
|
return planError('Firmware update plan executor contract is invalid');
|
|
760
760
|
}
|
|
@@ -879,10 +879,11 @@ const finalizeFirmwareUpdatePlan = ({ features, firmwareType, platform, artifact
|
|
|
879
879
|
const bootloaderMode = resolveDeviceBootloaderMode(features);
|
|
880
880
|
const reportedIdentity = getDeviceUUID(features);
|
|
881
881
|
const deviceIdentity = reportedIdentity === 'unavailable' ? '' : reportedIdentity;
|
|
882
|
+
const allowsUnavailableIdentity = (bootloaderMode && executor === 'v2') || executor === 'v4';
|
|
882
883
|
if (artifacts.length > 0 &&
|
|
883
884
|
(platform === 'native' || platform === 'desktop') &&
|
|
884
885
|
!deviceIdentity &&
|
|
885
|
-
!
|
|
886
|
+
!allowsUnavailableIdentity) {
|
|
886
887
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Prepared firmware update requires a stable device identity', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
|
|
887
888
|
}
|
|
888
889
|
const planWithoutDigest = {
|
|
@@ -1294,7 +1295,7 @@ const assertFirmwareUpdatePreparedPlanDeviceIdentity = ({ preparedPlan: value, d
|
|
|
1294
1295
|
}
|
|
1295
1296
|
const pinnedIdentity = degradedPlanIdentityPins.get(preparedPlan.leaseRef);
|
|
1296
1297
|
if (!deviceIdentity) {
|
|
1297
|
-
if (bootloaderMode !== true) {
|
|
1298
|
+
if (preparedPlan.executor !== 'v4' && bootloaderMode !== true) {
|
|
1298
1299
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
|
|
1299
1300
|
}
|
|
1300
1301
|
return preparedPlan;
|
|
@@ -47804,32 +47805,30 @@ class CheckAllFirmwareRelease extends BaseMethod {
|
|
|
47804
47805
|
...(forceResourceUpdate ? ['resource'] : []),
|
|
47805
47806
|
]));
|
|
47806
47807
|
let firmwareUpdatePlan;
|
|
47808
|
+
const shouldBuildFirmwareUpdatePlan = targetsToUpdate.length > 0;
|
|
47809
|
+
const requestedPlatform = platform !== null && platform !== void 0 ? platform : 'web';
|
|
47810
|
+
const requiresPreparedPlan = shouldBuildFirmwareUpdatePlan &&
|
|
47811
|
+
(requestedPlatform === 'native' || requestedPlatform === 'desktop');
|
|
47807
47812
|
try {
|
|
47808
|
-
const shouldBuildFirmwareUpdatePlan = targetsToUpdate.length > 0;
|
|
47809
|
-
const requestedPlatform = platform !== null && platform !== void 0 ? platform : 'web';
|
|
47810
|
-
const requiresDeviceIdentity = requestedPlatform === 'native' || requestedPlatform === 'desktop';
|
|
47811
|
-
const canBindPreparedPlan = !requiresDeviceIdentity || !!getDeviceSerialNo(features);
|
|
47812
47813
|
if (shouldBuildFirmwareUpdatePlan) {
|
|
47813
47814
|
const validatedPlan = buildProtocolV2FirmwareUpdatePlan({
|
|
47814
47815
|
features,
|
|
47815
47816
|
firmwareType,
|
|
47816
|
-
platform:
|
|
47817
|
+
platform: requestedPlatform,
|
|
47817
47818
|
release,
|
|
47818
47819
|
targetsToUpdate,
|
|
47819
47820
|
forceUpdateTargets: validatedForceUpdateTargets,
|
|
47820
47821
|
resourceArchive: resourceSource,
|
|
47821
47822
|
});
|
|
47822
|
-
firmwareUpdatePlan =
|
|
47823
|
-
if (!canBindPreparedPlan) {
|
|
47824
|
-
Log$c.warn('[CheckAllFirmwareRelease] Protocol V2 device identity is unavailable; using the release result without a prepared Plan');
|
|
47825
|
-
}
|
|
47823
|
+
firmwareUpdatePlan = validatedPlan;
|
|
47826
47824
|
}
|
|
47827
47825
|
else {
|
|
47828
47826
|
firmwareUpdatePlan = undefined;
|
|
47829
47827
|
}
|
|
47830
47828
|
}
|
|
47831
47829
|
catch (error) {
|
|
47832
|
-
if (
|
|
47830
|
+
if (requiresPreparedPlan ||
|
|
47831
|
+
validatedForceUpdateTargets.length > 0 ||
|
|
47833
47832
|
validatedProtocolV2ForceUpdateTargets.length > 0 ||
|
|
47834
47833
|
!(error instanceof hdShared.HardwareError) ||
|
|
47835
47834
|
((_a = error.params) === null || _a === void 0 ? void 0 : _a.firmwareUpdateCode) !== 'FirmwarePlanInvalid') {
|
|
@@ -49783,19 +49782,22 @@ class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod {
|
|
|
49783
49782
|
const { device } = this;
|
|
49784
49783
|
const { features } = device;
|
|
49785
49784
|
const payload = this.payload;
|
|
49786
|
-
const
|
|
49787
|
-
?
|
|
49785
|
+
const preparedPlan = payload.artifact
|
|
49786
|
+
? validateFirmwareUpdatePreparedPlan(payload.preparedPlan)
|
|
49787
|
+
: undefined;
|
|
49788
|
+
const hostBinding = preparedPlan
|
|
49789
|
+
? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration, preparedPlan.preparedPlanDigest)
|
|
49788
49790
|
: undefined;
|
|
49789
49791
|
const executionParams = Object.assign(Object.assign({}, payload), { artifactReader: (_a = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _a !== void 0 ? _a : payload.artifactReader });
|
|
49790
49792
|
if (payload.artifact) {
|
|
49791
49793
|
assertFirmwareUpdatePreparedPlanDeviceIdentity({
|
|
49792
|
-
preparedPlan
|
|
49794
|
+
preparedPlan,
|
|
49793
49795
|
deviceIdentity: getDeviceUUID(features) || undefined,
|
|
49794
49796
|
bootloaderMode: resolveDeviceBootloaderMode(features),
|
|
49795
49797
|
deviceModel: String(getDeviceType(features)),
|
|
49796
49798
|
});
|
|
49797
49799
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
49798
|
-
preparedPlan
|
|
49800
|
+
preparedPlan,
|
|
49799
49801
|
executor: 'v2',
|
|
49800
49802
|
scopeTargets: ['bootloader'],
|
|
49801
49803
|
bindings: [
|
|
@@ -50202,7 +50204,8 @@ class FirmwareUpdateV2 extends BaseMethod {
|
|
|
50202
50204
|
this.params = Object.assign(Object.assign({}, this.params), { binary: payload.binary });
|
|
50203
50205
|
}
|
|
50204
50206
|
if ('artifact' in payload) {
|
|
50205
|
-
const
|
|
50207
|
+
const preparedPlan = validateFirmwareUpdatePreparedPlan(payload.preparedPlan);
|
|
50208
|
+
const hostBinding = resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration, preparedPlan.preparedPlanDigest);
|
|
50206
50209
|
const target = payload.isUpdateBootloader ? 'bootloader' : payload.updateType;
|
|
50207
50210
|
const resourceBindings = ((_a = payload.resourceEntries) !== null && _a !== void 0 ? _a : []).map((entry) => ({
|
|
50208
50211
|
target: 'resource',
|
|
@@ -50210,13 +50213,13 @@ class FirmwareUpdateV2 extends BaseMethod {
|
|
|
50210
50213
|
artifact: entry.artifact,
|
|
50211
50214
|
}));
|
|
50212
50215
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
50213
|
-
preparedPlan
|
|
50216
|
+
preparedPlan,
|
|
50214
50217
|
executor: 'v2',
|
|
50215
50218
|
platform: payload.platform,
|
|
50216
50219
|
scopeTargets: [target, ...(target === 'firmware' ? ['resource'] : [])],
|
|
50217
50220
|
bindings: [{ target, artifact: payload.artifact }, ...resourceBindings],
|
|
50218
50221
|
});
|
|
50219
|
-
this.params = Object.assign(Object.assign({}, this.params), { preparedPlan
|
|
50222
|
+
this.params = Object.assign(Object.assign({}, this.params), { preparedPlan, artifact: payload.artifact, resourceEntries: payload.resourceEntries, artifactReader: hostBinding.artifactReader });
|
|
50220
50223
|
}
|
|
50221
50224
|
}
|
|
50222
50225
|
_promptDeviceInBootloaderForWebDevice() {
|
|
@@ -50579,12 +50582,15 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
50579
50582
|
{ name: 'firmwareType', type: 'string' },
|
|
50580
50583
|
{ name: 'platform', type: 'string' },
|
|
50581
50584
|
]);
|
|
50582
|
-
const
|
|
50583
|
-
?
|
|
50585
|
+
const preparedPlan = payload.artifacts || payload.preparedPlan
|
|
50586
|
+
? validateFirmwareUpdatePreparedPlan(payload.preparedPlan)
|
|
50587
|
+
: undefined;
|
|
50588
|
+
const hostBinding = preparedPlan
|
|
50589
|
+
? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration, preparedPlan.preparedPlanDigest)
|
|
50584
50590
|
: undefined;
|
|
50585
50591
|
if (hostBinding) {
|
|
50586
50592
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
50587
|
-
preparedPlan
|
|
50593
|
+
preparedPlan,
|
|
50588
50594
|
executor: 'v3',
|
|
50589
50595
|
platform: payload.platform,
|
|
50590
50596
|
scopeTargets: ['bootloader', 'firmware', 'resource', 'ble'],
|
|
@@ -50622,7 +50628,7 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
50622
50628
|
});
|
|
50623
50629
|
}
|
|
50624
50630
|
this.params = {
|
|
50625
|
-
preparedPlan
|
|
50631
|
+
preparedPlan,
|
|
50626
50632
|
bleBinary: payload.bleBinary,
|
|
50627
50633
|
firmwareBinary: payload.firmwareBinary,
|
|
50628
50634
|
forcedUpdateRes: payload.forcedUpdateRes,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.90",
|
|
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.0-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.90",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.90",
|
|
30
30
|
"axios": "1.15.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
32
|
"bytebuffer": "^5.0.1",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"@types/w3c-web-usb": "^1.0.10",
|
|
45
45
|
"@types/web-bluetooth": "^0.0.21"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "e8271225634f3058498af8beee06d9de705b6710"
|
|
48
48
|
}
|
|
@@ -28,7 +28,6 @@ import { getBridgeReleaseInfo } from '../utils/bridgeUpdate';
|
|
|
28
28
|
import {
|
|
29
29
|
LoggerNames,
|
|
30
30
|
getDeviceFirmwareVersion,
|
|
31
|
-
getDeviceSerialNo,
|
|
32
31
|
getDeviceType,
|
|
33
32
|
getFirmwareType,
|
|
34
33
|
getLogger,
|
|
@@ -437,33 +436,29 @@ export default class CheckAllFirmwareRelease extends BaseMethod {
|
|
|
437
436
|
])
|
|
438
437
|
);
|
|
439
438
|
let firmwareUpdatePlan: FirmwareUpdatePlan | undefined;
|
|
439
|
+
const shouldBuildFirmwareUpdatePlan = targetsToUpdate.length > 0;
|
|
440
|
+
const requestedPlatform = platform ?? 'web';
|
|
441
|
+
const requiresPreparedPlan =
|
|
442
|
+
shouldBuildFirmwareUpdatePlan &&
|
|
443
|
+
(requestedPlatform === 'native' || requestedPlatform === 'desktop');
|
|
440
444
|
try {
|
|
441
|
-
const shouldBuildFirmwareUpdatePlan = targetsToUpdate.length > 0;
|
|
442
|
-
const requestedPlatform = platform ?? 'web';
|
|
443
|
-
const requiresDeviceIdentity =
|
|
444
|
-
requestedPlatform === 'native' || requestedPlatform === 'desktop';
|
|
445
|
-
const canBindPreparedPlan = !requiresDeviceIdentity || !!getDeviceSerialNo(features);
|
|
446
445
|
if (shouldBuildFirmwareUpdatePlan) {
|
|
447
446
|
const validatedPlan = buildProtocolV2FirmwareUpdatePlan({
|
|
448
447
|
features,
|
|
449
448
|
firmwareType,
|
|
450
|
-
platform:
|
|
449
|
+
platform: requestedPlatform,
|
|
451
450
|
release,
|
|
452
451
|
targetsToUpdate,
|
|
453
452
|
forceUpdateTargets: validatedForceUpdateTargets,
|
|
454
453
|
resourceArchive: resourceSource,
|
|
455
454
|
});
|
|
456
|
-
firmwareUpdatePlan =
|
|
457
|
-
if (!canBindPreparedPlan) {
|
|
458
|
-
Log.warn(
|
|
459
|
-
'[CheckAllFirmwareRelease] Protocol V2 device identity is unavailable; using the release result without a prepared Plan'
|
|
460
|
-
);
|
|
461
|
-
}
|
|
455
|
+
firmwareUpdatePlan = validatedPlan;
|
|
462
456
|
} else {
|
|
463
457
|
firmwareUpdatePlan = undefined;
|
|
464
458
|
}
|
|
465
459
|
} catch (error) {
|
|
466
460
|
if (
|
|
461
|
+
requiresPreparedPlan ||
|
|
467
462
|
validatedForceUpdateTargets.length > 0 ||
|
|
468
463
|
validatedProtocolV2ForceUpdateTargets.length > 0 ||
|
|
469
464
|
!(error instanceof HardwareError) ||
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
assertFirmwareUpdatePreparedPlanBinding,
|
|
34
34
|
assertFirmwareUpdatePreparedPlanDeviceIdentity,
|
|
35
35
|
getFirmwareUpdateResourceName,
|
|
36
|
+
validateFirmwareUpdatePreparedPlan,
|
|
36
37
|
} from './firmware/FirmwareUpdatePreparedPlan';
|
|
37
38
|
|
|
38
39
|
import type { Features, KnownDevice } from '../types';
|
|
@@ -200,7 +201,11 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
200
201
|
}
|
|
201
202
|
|
|
202
203
|
if ('artifact' in payload) {
|
|
203
|
-
const
|
|
204
|
+
const preparedPlan = validateFirmwareUpdatePreparedPlan(payload.preparedPlan);
|
|
205
|
+
const hostBinding = resolveFirmwareUpdateHostBinding(
|
|
206
|
+
payload.hostBindingGeneration,
|
|
207
|
+
preparedPlan.preparedPlanDigest
|
|
208
|
+
);
|
|
204
209
|
const target = payload.isUpdateBootloader ? 'bootloader' : payload.updateType;
|
|
205
210
|
const resourceBindings = (payload.resourceEntries ?? []).map(
|
|
206
211
|
(entry: { entryName: string; artifact: FirmwareArtifactReference }) => ({
|
|
@@ -210,7 +215,7 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
210
215
|
})
|
|
211
216
|
);
|
|
212
217
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
213
|
-
preparedPlan
|
|
218
|
+
preparedPlan,
|
|
214
219
|
executor: 'v2',
|
|
215
220
|
platform: payload.platform,
|
|
216
221
|
scopeTargets: [target, ...(target === 'firmware' ? (['resource'] as const) : [])],
|
|
@@ -218,7 +223,7 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
218
223
|
});
|
|
219
224
|
this.params = {
|
|
220
225
|
...this.params,
|
|
221
|
-
preparedPlan
|
|
226
|
+
preparedPlan,
|
|
222
227
|
artifact: payload.artifact,
|
|
223
228
|
resourceEntries: payload.resourceEntries,
|
|
224
229
|
artifactReader: hostBinding.artifactReader,
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
assertFirmwareUpdatePreparedPlanBinding,
|
|
26
26
|
assertFirmwareUpdatePreparedPlanDeviceIdentity,
|
|
27
27
|
getFirmwareUpdateResourceName,
|
|
28
|
+
validateFirmwareUpdatePreparedPlan,
|
|
28
29
|
} from './firmware/FirmwareUpdatePreparedPlan';
|
|
29
30
|
|
|
30
31
|
import type {
|
|
@@ -77,13 +78,19 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
77
78
|
{ name: 'firmwareType', type: 'string' },
|
|
78
79
|
{ name: 'platform', type: 'string' },
|
|
79
80
|
]);
|
|
80
|
-
const
|
|
81
|
+
const preparedPlan =
|
|
81
82
|
payload.artifacts || payload.preparedPlan
|
|
82
|
-
?
|
|
83
|
+
? validateFirmwareUpdatePreparedPlan(payload.preparedPlan)
|
|
83
84
|
: undefined;
|
|
85
|
+
const hostBinding = preparedPlan
|
|
86
|
+
? resolveFirmwareUpdateHostBinding(
|
|
87
|
+
payload.hostBindingGeneration,
|
|
88
|
+
preparedPlan.preparedPlanDigest
|
|
89
|
+
)
|
|
90
|
+
: undefined;
|
|
84
91
|
if (hostBinding) {
|
|
85
92
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
86
|
-
preparedPlan
|
|
93
|
+
preparedPlan,
|
|
87
94
|
executor: 'v3',
|
|
88
95
|
platform: payload.platform,
|
|
89
96
|
scopeTargets: ['bootloader', 'firmware', 'resource', 'ble'],
|
|
@@ -124,7 +131,7 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
124
131
|
}
|
|
125
132
|
|
|
126
133
|
this.params = {
|
|
127
|
-
preparedPlan
|
|
134
|
+
preparedPlan,
|
|
128
135
|
bleBinary: payload.bleBinary,
|
|
129
136
|
firmwareBinary: payload.firmwareBinary,
|
|
130
137
|
forcedUpdateRes: payload.forcedUpdateRes,
|
|
@@ -14,6 +14,7 @@ import { resolveFirmwareUpdateHostBinding } from '../firmware/FirmwareHostBindin
|
|
|
14
14
|
import {
|
|
15
15
|
assertFirmwareUpdatePreparedPlanBinding,
|
|
16
16
|
assertFirmwareUpdatePreparedPlanDeviceIdentity,
|
|
17
|
+
validateFirmwareUpdatePreparedPlan,
|
|
17
18
|
} from '../firmware/FirmwareUpdatePreparedPlan';
|
|
18
19
|
import { getDeviceType, getDeviceUUID } from '../../utils';
|
|
19
20
|
import { resolveDeviceBootloaderMode } from '../../utils/deviceFeaturesCompat';
|
|
@@ -157,8 +158,14 @@ export default class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod<any
|
|
|
157
158
|
const { features } = device;
|
|
158
159
|
|
|
159
160
|
const payload = this.payload as DeviceUpdateBootloaderParams;
|
|
160
|
-
const
|
|
161
|
-
?
|
|
161
|
+
const preparedPlan = payload.artifact
|
|
162
|
+
? validateFirmwareUpdatePreparedPlan(payload.preparedPlan)
|
|
163
|
+
: undefined;
|
|
164
|
+
const hostBinding = preparedPlan
|
|
165
|
+
? resolveFirmwareUpdateHostBinding(
|
|
166
|
+
payload.hostBindingGeneration,
|
|
167
|
+
preparedPlan.preparedPlanDigest
|
|
168
|
+
)
|
|
162
169
|
: undefined;
|
|
163
170
|
const executionParams = {
|
|
164
171
|
...payload,
|
|
@@ -166,13 +173,13 @@ export default class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod<any
|
|
|
166
173
|
};
|
|
167
174
|
if (payload.artifact) {
|
|
168
175
|
assertFirmwareUpdatePreparedPlanDeviceIdentity({
|
|
169
|
-
preparedPlan
|
|
176
|
+
preparedPlan,
|
|
170
177
|
deviceIdentity: getDeviceUUID(features) || undefined,
|
|
171
178
|
bootloaderMode: resolveDeviceBootloaderMode(features),
|
|
172
179
|
deviceModel: String(getDeviceType(features)),
|
|
173
180
|
});
|
|
174
181
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
175
|
-
preparedPlan
|
|
182
|
+
preparedPlan,
|
|
176
183
|
executor: 'v2',
|
|
177
184
|
scopeTargets: ['bootloader'],
|
|
178
185
|
bindings: [
|
|
@@ -373,13 +373,11 @@ export const assertFirmwareUpdatePlan = (value: unknown): FirmwareUpdatePlan =>
|
|
|
373
373
|
plan.targetsToUpdate.some(target =>
|
|
374
374
|
legacyOnlyTargets.has(target as FirmwareUpdatePlanTarget)
|
|
375
375
|
)) ||
|
|
376
|
-
//
|
|
377
|
-
//
|
|
378
|
-
// must always carry a real identity. Degraded v2 plans are bound to the live
|
|
379
|
-
// device at install time instead.
|
|
376
|
+
// V2 仅在 bootloader 恢复时允许缺少身份;V4 设备在尚未写入序列号时也可升级。
|
|
377
|
+
// 这类 Plan 仍通过设备型号、目标、工件摘要与 preparedPlanDigest 进行约束。
|
|
380
378
|
(plan.artifacts.length > 0 &&
|
|
381
379
|
(plan.platform === 'native' || plan.platform === 'desktop') &&
|
|
382
|
-
plan.executor
|
|
380
|
+
plan.executor === 'v3' &&
|
|
383
381
|
plan.deviceIdentity === 'unavailable')
|
|
384
382
|
) {
|
|
385
383
|
return planError('Firmware update plan executor contract is invalid');
|
|
@@ -603,16 +601,14 @@ const finalizeFirmwareUpdatePlan = ({
|
|
|
603
601
|
// serial must never be able to collide with it.
|
|
604
602
|
const reportedIdentity = getDeviceUUID(features);
|
|
605
603
|
const deviceIdentity = reportedIdentity === 'unavailable' ? '' : reportedIdentity;
|
|
606
|
-
//
|
|
607
|
-
//
|
|
608
|
-
|
|
609
|
-
// (assertFirmwareUpdatePreparedPlanDeviceIdentity), and plan integrity by the digest.
|
|
610
|
-
// Pro (v3), Pro2, and Neo (v4) report a serial even in loader mode and stay strict.
|
|
604
|
+
// Classic 系列仅在 bootloader 恢复时允许缺少身份;部分尚未完成产线写号的
|
|
605
|
+
// Pro2/Neo(V4)在正常模式下也可能没有序列号,因此允许使用降级身份。
|
|
606
|
+
const allowsUnavailableIdentity = (bootloaderMode && executor === 'v2') || executor === 'v4';
|
|
611
607
|
if (
|
|
612
608
|
artifacts.length > 0 &&
|
|
613
609
|
(platform === 'native' || platform === 'desktop') &&
|
|
614
610
|
!deviceIdentity &&
|
|
615
|
-
!
|
|
611
|
+
!allowsUnavailableIdentity
|
|
616
612
|
) {
|
|
617
613
|
throw ERRORS.TypedError(
|
|
618
614
|
HardwareErrorCode.RuntimeError,
|
|
@@ -349,8 +349,8 @@ export const assertFirmwareUpdatePreparedPlanDeviceIdentity = ({
|
|
|
349
349
|
}
|
|
350
350
|
const pinnedIdentity = degradedPlanIdentityPins.get(preparedPlan.leaseRef);
|
|
351
351
|
if (!deviceIdentity) {
|
|
352
|
-
//
|
|
353
|
-
if (bootloaderMode !== true) {
|
|
352
|
+
// V4 设备可能尚未写入序列号;V2 则只允许 bootloader 恢复流程缺少身份。
|
|
353
|
+
if (preparedPlan.executor !== 'v4' && bootloaderMode !== true) {
|
|
354
354
|
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
|
|
355
355
|
}
|
|
356
356
|
return preparedPlan;
|