@onekeyfe/hd-core 1.2.0-alpha.95 → 1.2.0-alpha.97
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 +84 -404
- package/__tests__/firmware-update/device-update-bootloader.test.ts +2 -6
- package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -9
- package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +112 -0
- package/__tests__/firmware-update/firmware-update-plan.test.ts +70 -131
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +1 -53
- package/__tests__/protocol-v2-resources.test.ts +232 -148
- package/__tests__/protocol-v2.test.ts +517 -1106
- package/dist/api/CheckAllFirmwareRelease.d.ts +3 -2
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CheckBLEFirmwareRelease.d.ts +2 -3
- package/dist/api/CheckBLEFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CheckBootloaderRelease.d.ts +1 -2
- package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
- package/dist/api/CheckFirmwareRelease.d.ts +2 -3
- package/dist/api/CheckFirmwareRelease.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +0 -1
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +8 -6
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/UploadPortfolio.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareHostBinding.d.ts +1 -1
- package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +1 -48
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +1 -0
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +3 -4
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/index.d.ts +111 -103
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +849 -1301
- package/dist/protocols/protocol-v2/resources.d.ts +28 -10
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts +8 -20
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/checkBLEFirmwareRelease.d.ts +13 -2
- package/dist/types/api/checkBLEFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/checkBootloaderRelease.d.ts +6 -2
- package/dist/types/api/checkBootloaderRelease.d.ts.map +1 -1
- package/dist/types/api/checkFirmwareRelease.d.ts +13 -2
- package/dist/types/api/checkFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/checkFirmwareTypeAvailable.d.ts +2 -2
- package/dist/types/api/checkFirmwareTypeAvailable.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +1 -1
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +11 -3
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/settings.d.ts +36 -35
- package/dist/types/settings.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/CheckAllFirmwareRelease.ts +80 -108
- package/src/api/CheckBLEFirmwareRelease.ts +5 -37
- package/src/api/CheckBootloaderRelease.ts +3 -35
- package/src/api/CheckFirmwareRelease.ts +7 -35
- package/src/api/FirmwareUpdateV2.ts +3 -15
- package/src/api/FirmwareUpdateV3.ts +6 -13
- package/src/api/FirmwareUpdateV4.ts +407 -824
- package/src/api/UploadPortfolio.ts +0 -18
- package/src/api/device/DeviceUpdateBootloader.ts +5 -26
- package/src/api/firmware/FirmwareHostBinding.ts +3 -16
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +2 -0
- package/src/api/firmware/FirmwareUpdatePlan.ts +88 -226
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +3 -10
- package/src/data-manager/DataManager.ts +19 -35
- package/src/index.ts +0 -10
- package/src/protocols/protocol-v2/resources.ts +341 -157
- package/src/types/api/checkAllFirmwareRelease.ts +12 -27
- package/src/types/api/checkBLEFirmwareRelease.ts +13 -4
- package/src/types/api/checkBootloaderRelease.ts +6 -2
- package/src/types/api/checkFirmwareRelease.ts +13 -2
- package/src/types/api/checkFirmwareTypeAvailable.ts +2 -2
- package/src/types/api/export.ts +1 -6
- package/src/types/api/firmwareUpdate.ts +16 -10
- package/src/types/settings.ts +61 -35
- package/src/utils/deviceFeaturesUtils.ts +2 -2
- package/__tests__/check-firmware-release-protocol-v2.test.ts +0 -199
- package/__tests__/firmware-memory-host.test.ts +0 -112
- package/__tests__/firmware-update/firmware-prepared-host-digest.test.ts +0 -448
- package/dist/api/firmware/FirmwareMemoryHost.d.ts +0 -22
- package/dist/api/firmware/FirmwareMemoryHost.d.ts.map +0 -1
- package/dist/api/firmware/protocolV2Release.d.ts +0 -33
- package/dist/api/firmware/protocolV2Release.d.ts.map +0 -1
- package/src/api/firmware/FirmwareMemoryHost.ts +0 -142
- package/src/api/firmware/protocolV2Release.ts +0 -168
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { EDeviceType } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
1
3
|
import FirmwareUpdate from '../../src/api/FirmwareUpdate';
|
|
2
4
|
import FirmwareUpdateV2 from '../../src/api/FirmwareUpdateV2';
|
|
3
5
|
import FirmwareUpdateV3 from '../../src/api/FirmwareUpdateV3';
|
|
4
6
|
import { BOOTLOADER_POLL_INITIALIZE_TIMEOUT_MS } from '../../src/api/firmware/FirmwareUpdateBaseMethod';
|
|
5
7
|
import { DataManager } from '../../src/data-manager';
|
|
8
|
+
import { DevicePool } from '../../src/device/DevicePool';
|
|
6
9
|
|
|
7
10
|
import type { Device } from '../../src/device/Device';
|
|
8
11
|
|
|
@@ -12,6 +15,7 @@ jest.mock('../../src/data/config', () => ({
|
|
|
12
15
|
}));
|
|
13
16
|
|
|
14
17
|
const BLE_ID = 'ble-device';
|
|
18
|
+
const WEBUSB_ID = 'webusb-device';
|
|
15
19
|
|
|
16
20
|
const flush = () =>
|
|
17
21
|
new Promise(resolve => {
|
|
@@ -198,3 +202,111 @@ describe.each([
|
|
|
198
202
|
expect(maxActiveProbes).toBe(1);
|
|
199
203
|
});
|
|
200
204
|
});
|
|
205
|
+
|
|
206
|
+
describe.each([
|
|
207
|
+
[
|
|
208
|
+
'FirmwareUpdateV2',
|
|
209
|
+
() =>
|
|
210
|
+
new FirmwareUpdateV2({
|
|
211
|
+
id: 1,
|
|
212
|
+
payload: { method: 'firmwareUpdateV2', connectId: WEBUSB_ID },
|
|
213
|
+
}),
|
|
214
|
+
],
|
|
215
|
+
[
|
|
216
|
+
'FirmwareUpdateV3 (base method)',
|
|
217
|
+
() =>
|
|
218
|
+
new FirmwareUpdateV3({
|
|
219
|
+
id: 1,
|
|
220
|
+
payload: { method: 'firmwareUpdateV3', connectId: WEBUSB_ID },
|
|
221
|
+
}),
|
|
222
|
+
],
|
|
223
|
+
])('%s WebUSB bootloader authorization', (_name, buildMethod) => {
|
|
224
|
+
beforeEach(() => {
|
|
225
|
+
jest.useFakeTimers({ doNotFake: ['setImmediate', 'performance'] });
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
afterEach(() => {
|
|
229
|
+
jest.clearAllTimers();
|
|
230
|
+
jest.useRealTimers();
|
|
231
|
+
jest.restoreAllMocks();
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test('pauses the reboot deadline while waiting for browser authorization', async () => {
|
|
235
|
+
jest.spyOn(DataManager, 'getSettings').mockReturnValue('webusb' as never);
|
|
236
|
+
jest.spyOn(DataManager, 'isBleConnect').mockReturnValue(false);
|
|
237
|
+
jest.spyOn(DataManager, 'isBrowserWebUsb').mockReturnValue(true);
|
|
238
|
+
|
|
239
|
+
const method = buildMethod();
|
|
240
|
+
let permissionGranted = false;
|
|
241
|
+
const bootloaderDevice = {
|
|
242
|
+
isBootloader: jest.fn(() => true),
|
|
243
|
+
} as unknown as Device;
|
|
244
|
+
jest.spyOn(DevicePool, 'getDevices').mockImplementation(() =>
|
|
245
|
+
Promise.resolve({
|
|
246
|
+
devices: {},
|
|
247
|
+
deviceList: permissionGranted ? [bootloaderDevice] : [],
|
|
248
|
+
})
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
const commands = { disposed: true };
|
|
252
|
+
const updateFromCache = jest.fn();
|
|
253
|
+
method.device = {
|
|
254
|
+
originalDescriptor: {
|
|
255
|
+
id: WEBUSB_ID,
|
|
256
|
+
path: WEBUSB_ID,
|
|
257
|
+
protocolType: 'V1',
|
|
258
|
+
},
|
|
259
|
+
deviceConnector: {
|
|
260
|
+
enumerate: jest.fn(() =>
|
|
261
|
+
Promise.resolve({
|
|
262
|
+
descriptors: permissionGranted ? [{ path: 'bootloader-device' }] : [],
|
|
263
|
+
})
|
|
264
|
+
),
|
|
265
|
+
},
|
|
266
|
+
commands,
|
|
267
|
+
updateFromCache,
|
|
268
|
+
getCurrentDeviceType: jest.fn(() => EDeviceType.Pro),
|
|
269
|
+
} as unknown as Device;
|
|
270
|
+
method.postTipMessage = jest.fn();
|
|
271
|
+
|
|
272
|
+
let resolvePrompt: (deviceId: string) => void = () => undefined;
|
|
273
|
+
const promptPromise = new Promise<string>(resolve => {
|
|
274
|
+
resolvePrompt = resolve;
|
|
275
|
+
});
|
|
276
|
+
const prompt = jest
|
|
277
|
+
.spyOn(method as any, '_promptDeviceInBootloaderForWebDevice')
|
|
278
|
+
.mockReturnValue(promptPromise);
|
|
279
|
+
|
|
280
|
+
method.checkDeviceToBootloader(WEBUSB_ID);
|
|
281
|
+
const resolved = jest.fn();
|
|
282
|
+
const rejected = jest.fn();
|
|
283
|
+
method.checkPromise?.promise.then(resolved, rejected);
|
|
284
|
+
|
|
285
|
+
for (let elapsed = 0; elapsed < 15000; elapsed += 500) {
|
|
286
|
+
jest.advanceTimersByTime(500);
|
|
287
|
+
// eslint-disable-next-line no-await-in-loop
|
|
288
|
+
await flush();
|
|
289
|
+
if (prompt.mock.calls.length) break;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
expect(prompt).toHaveBeenCalledTimes(1);
|
|
293
|
+
|
|
294
|
+
// Browser permission depends on a user gesture and must not consume the
|
|
295
|
+
// automatic reboot detection deadline.
|
|
296
|
+
for (let elapsed = 0; elapsed < 35000; elapsed += 500) {
|
|
297
|
+
jest.advanceTimersByTime(500);
|
|
298
|
+
// eslint-disable-next-line no-await-in-loop
|
|
299
|
+
await flush();
|
|
300
|
+
}
|
|
301
|
+
expect(rejected).not.toHaveBeenCalled();
|
|
302
|
+
|
|
303
|
+
permissionGranted = true;
|
|
304
|
+
resolvePrompt('bootloader-device');
|
|
305
|
+
await flush();
|
|
306
|
+
await flush();
|
|
307
|
+
|
|
308
|
+
expect(resolved).toHaveBeenCalledWith(true);
|
|
309
|
+
expect(updateFromCache).toHaveBeenCalledWith(bootloaderDevice);
|
|
310
|
+
expect(commands.disposed).toBe(false);
|
|
311
|
+
});
|
|
312
|
+
});
|
|
@@ -1,10 +1,6 @@
|
|
|
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';
|
|
8
4
|
|
|
9
5
|
import type { Features } from '../../src/types';
|
|
10
6
|
|
|
@@ -301,6 +297,12 @@ describe('buildFirmwareUpdatePlan', () => {
|
|
|
301
297
|
forceTarget: 'firmware' as const,
|
|
302
298
|
release: {
|
|
303
299
|
components: {},
|
|
300
|
+
resourceBundles: [
|
|
301
|
+
{
|
|
302
|
+
name: 'images',
|
|
303
|
+
url: 'https://firmware.onekey.so/pro2/images.okpkg',
|
|
304
|
+
},
|
|
305
|
+
],
|
|
304
306
|
},
|
|
305
307
|
},
|
|
306
308
|
{
|
|
@@ -310,8 +312,6 @@ describe('buildFirmwareUpdatePlan', () => {
|
|
|
310
312
|
applicationP1: {
|
|
311
313
|
target: 'APPLICATION_P1',
|
|
312
314
|
url: 'https://firmware.onekey.so/pro2/application-p1.bin',
|
|
313
|
-
expectedSize: 1024,
|
|
314
|
-
fingerprint: '1111111111111111111111111111111111111111111111111111111111111111',
|
|
315
315
|
},
|
|
316
316
|
},
|
|
317
317
|
},
|
|
@@ -325,23 +325,41 @@ describe('buildFirmwareUpdatePlan', () => {
|
|
|
325
325
|
}
|
|
326
326
|
);
|
|
327
327
|
|
|
328
|
-
test(
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
328
|
+
test.each([
|
|
329
|
+
{
|
|
330
|
+
forceTarget: 'firmware' as const,
|
|
331
|
+
expectedArtifactIds: ['component:app_v1'],
|
|
332
|
+
expectedTargets: ['app_v1'],
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
forceTarget: 'resource' as const,
|
|
336
|
+
expectedArtifactIds: ['resourceBundle:images'],
|
|
337
|
+
expectedTargets: ['resource'],
|
|
338
|
+
},
|
|
339
|
+
])(
|
|
340
|
+
'limits a Pro2 $forceTarget force to the selected artifact role',
|
|
341
|
+
({ forceTarget, expectedArtifactIds, expectedTargets }) => {
|
|
342
|
+
const plan = buildFirmwareUpdatePlan(
|
|
343
|
+
createProtocolV2ForceInput([forceTarget], {
|
|
344
|
+
components: {
|
|
345
|
+
applicationP1: {
|
|
346
|
+
target: 'APPLICATION_P1',
|
|
347
|
+
url: 'https://firmware.onekey.so/pro2/application-p1.bin',
|
|
348
|
+
},
|
|
337
349
|
},
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
350
|
+
resourceBundles: [
|
|
351
|
+
{
|
|
352
|
+
name: 'images',
|
|
353
|
+
url: 'https://firmware.onekey.so/pro2/images.okpkg',
|
|
354
|
+
},
|
|
355
|
+
],
|
|
356
|
+
})
|
|
357
|
+
);
|
|
341
358
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
359
|
+
expect(plan.artifacts.map(artifact => artifact.artifactId)).toEqual(expectedArtifactIds);
|
|
360
|
+
expect(plan.targetsToUpdate).toEqual(expectedTargets);
|
|
361
|
+
}
|
|
362
|
+
);
|
|
345
363
|
|
|
346
364
|
test('rejects a prepared native plan without a stable device identity', () => {
|
|
347
365
|
const features = createFeatures({
|
|
@@ -366,72 +384,7 @@ describe('buildFirmwareUpdatePlan', () => {
|
|
|
366
384
|
).toThrow('requires a stable device identity');
|
|
367
385
|
});
|
|
368
386
|
|
|
369
|
-
test('
|
|
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
|
-
|
|
434
|
-
test('maps the Pro2 component order without downloading artifacts', () => {
|
|
387
|
+
test('maps the Pro2 component order and resource bundles without downloading them', () => {
|
|
435
388
|
const plan = buildFirmwareUpdatePlan({
|
|
436
389
|
features: createFeatures({ deviceType: EDeviceType.Pro2 }),
|
|
437
390
|
firmwareType: EFirmwareType.Universal,
|
|
@@ -450,16 +403,18 @@ describe('buildFirmwareUpdatePlan', () => {
|
|
|
450
403
|
bootloader: {
|
|
451
404
|
target: 'BOOTLOADER',
|
|
452
405
|
url: 'https://firmware.onekey.so/pro2/bootloader.bin',
|
|
453
|
-
expectedSize: 2048,
|
|
454
|
-
fingerprint: '2222222222222222222222222222222222222222222222222222222222222222',
|
|
455
406
|
},
|
|
456
407
|
se01: {
|
|
457
408
|
target: 'SE01',
|
|
458
409
|
url: 'https://firmware.onekey.so/pro2/se01.bin',
|
|
459
|
-
expectedSize: 512,
|
|
460
|
-
fingerprint: '3333333333333333333333333333333333333333333333333333333333333333',
|
|
461
410
|
},
|
|
462
411
|
},
|
|
412
|
+
resourceBundles: [
|
|
413
|
+
{
|
|
414
|
+
name: 'images',
|
|
415
|
+
url: 'https://firmware.onekey.so/pro2/images.okpkg',
|
|
416
|
+
},
|
|
417
|
+
],
|
|
463
418
|
},
|
|
464
419
|
},
|
|
465
420
|
ble: noUpdate,
|
|
@@ -471,8 +426,9 @@ describe('buildFirmwareUpdatePlan', () => {
|
|
|
471
426
|
'component:boot',
|
|
472
427
|
'component:app_v1',
|
|
473
428
|
'component:se01',
|
|
429
|
+
'resourceBundle:images',
|
|
474
430
|
]);
|
|
475
|
-
expect(plan.targetsToUpdate).toEqual(['boot', 'app_v1', 'se01']);
|
|
431
|
+
expect(plan.targetsToUpdate).toEqual(['boot', 'app_v1', 'se01', 'resource']);
|
|
476
432
|
expect(plan.artifacts[1]).toEqual(
|
|
477
433
|
expect.objectContaining({
|
|
478
434
|
expectedSize: 1024,
|
|
@@ -481,41 +437,6 @@ describe('buildFirmwareUpdatePlan', () => {
|
|
|
481
437
|
);
|
|
482
438
|
});
|
|
483
439
|
|
|
484
|
-
test.each([
|
|
485
|
-
{
|
|
486
|
-
expectedSize: undefined,
|
|
487
|
-
fingerprint: '1'.repeat(64),
|
|
488
|
-
},
|
|
489
|
-
{
|
|
490
|
-
expectedSize: 1024,
|
|
491
|
-
fingerprint: undefined,
|
|
492
|
-
},
|
|
493
|
-
])('rejects a remote Pro2 component without complete integrity metadata', integrity => {
|
|
494
|
-
expectFirmwarePlanInvalid(
|
|
495
|
-
() =>
|
|
496
|
-
buildFirmwareUpdatePlan({
|
|
497
|
-
features: createFeatures({ deviceType: EDeviceType.Pro2 }),
|
|
498
|
-
firmwareType: EFirmwareType.Universal,
|
|
499
|
-
platform: 'desktop',
|
|
500
|
-
firmware: {
|
|
501
|
-
status: 'required',
|
|
502
|
-
release: {
|
|
503
|
-
components: {
|
|
504
|
-
applicationP1: {
|
|
505
|
-
target: 'APPLICATION_P1',
|
|
506
|
-
url: 'https://firmware.onekey.so/pro2/application-p1.bin',
|
|
507
|
-
...integrity,
|
|
508
|
-
},
|
|
509
|
-
},
|
|
510
|
-
},
|
|
511
|
-
},
|
|
512
|
-
ble: noUpdate,
|
|
513
|
-
bootloader: noUpdate,
|
|
514
|
-
}),
|
|
515
|
-
'integrity metadata is invalid'
|
|
516
|
-
);
|
|
517
|
-
});
|
|
518
|
-
|
|
519
440
|
test('rejects Pro2 ROMLOADER because it requires a separate loader flow', () => {
|
|
520
441
|
expect(() =>
|
|
521
442
|
buildFirmwareUpdatePlan({
|
|
@@ -547,19 +468,37 @@ describe('buildFirmwareUpdatePlan', () => {
|
|
|
547
468
|
application: {
|
|
548
469
|
target: 'APPLICATION_P1',
|
|
549
470
|
url: 'https://firmware.onekey.so/pro2/application.bin',
|
|
550
|
-
expectedSize: 1024,
|
|
551
|
-
fingerprint: '1111111111111111111111111111111111111111111111111111111111111111',
|
|
552
471
|
},
|
|
553
472
|
applicationDuplicate: {
|
|
554
473
|
target: 'APPLICATION_P1',
|
|
555
474
|
url: 'https://firmware.onekey.so/pro2/application-duplicate.bin',
|
|
556
|
-
expectedSize: 1024,
|
|
557
|
-
fingerprint: '2222222222222222222222222222222222222222222222222222222222222222',
|
|
558
475
|
},
|
|
559
476
|
},
|
|
560
477
|
},
|
|
561
478
|
expectedError: 'duplicates target app_v1',
|
|
562
479
|
},
|
|
480
|
+
{
|
|
481
|
+
label: 'resource bundle name',
|
|
482
|
+
release: {
|
|
483
|
+
components: {
|
|
484
|
+
application: {
|
|
485
|
+
target: 'APPLICATION_P1',
|
|
486
|
+
url: 'https://firmware.onekey.so/pro2/application.bin',
|
|
487
|
+
},
|
|
488
|
+
},
|
|
489
|
+
resourceBundles: [
|
|
490
|
+
{
|
|
491
|
+
name: 'images',
|
|
492
|
+
url: 'https://firmware.onekey.so/pro2/images.okpkg',
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
name: 'images',
|
|
496
|
+
url: 'https://firmware.onekey.so/pro2/images-duplicate.okpkg',
|
|
497
|
+
},
|
|
498
|
+
],
|
|
499
|
+
},
|
|
500
|
+
expectedError: 'duplicates name images',
|
|
501
|
+
},
|
|
563
502
|
])('rejects a duplicate Pro2 $label', ({ release, expectedError }) => {
|
|
564
503
|
expect(() =>
|
|
565
504
|
buildFirmwareUpdatePlan({
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { EDeviceType, EFirmwareType } from '@onekeyfe/hd-shared';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
buildFirmwareUpdatePlan,
|
|
5
|
-
digestFirmwareUpdateContract,
|
|
6
|
-
} from '../../src/api/firmware/FirmwareUpdatePlan';
|
|
3
|
+
import { buildFirmwareUpdatePlan } from '../../src/api/firmware/FirmwareUpdatePlan';
|
|
7
4
|
import {
|
|
8
5
|
assertFirmwareUpdatePreparedPlanBinding,
|
|
9
6
|
assertFirmwareUpdatePreparedPlanDeviceIdentity,
|
|
@@ -212,55 +209,6 @@ describe('FirmwareUpdatePreparedPlan', () => {
|
|
|
212
209
|
).toThrow('entry name is invalid');
|
|
213
210
|
});
|
|
214
211
|
|
|
215
|
-
test('rejects duplicate materialized entry names during standalone validation', () => {
|
|
216
|
-
const plan = buildPlan();
|
|
217
|
-
const prepared = prepareFirmwareUpdatePlan({
|
|
218
|
-
plan,
|
|
219
|
-
leaseRef: 'fwlease:00000000-0000-4000-8000-000000000001',
|
|
220
|
-
artifacts: [
|
|
221
|
-
{
|
|
222
|
-
artifactId: 'firmware',
|
|
223
|
-
artifact: artifact('a'.repeat(64), 4),
|
|
224
|
-
},
|
|
225
|
-
{
|
|
226
|
-
artifactId: 'resource',
|
|
227
|
-
artifact: artifact('b'.repeat(64), 8),
|
|
228
|
-
materializedEntries: [
|
|
229
|
-
{
|
|
230
|
-
entryName: 'resource/index.bin',
|
|
231
|
-
artifact: artifact('c'.repeat(64), 2),
|
|
232
|
-
},
|
|
233
|
-
],
|
|
234
|
-
},
|
|
235
|
-
],
|
|
236
|
-
});
|
|
237
|
-
const resourceArtifact = prepared.artifacts.find(item => item.target === 'resource')!;
|
|
238
|
-
const tamperedWithoutDigest = {
|
|
239
|
-
...prepared,
|
|
240
|
-
artifacts: prepared.artifacts.map(item =>
|
|
241
|
-
item === resourceArtifact
|
|
242
|
-
? {
|
|
243
|
-
...item,
|
|
244
|
-
materializedEntries: [
|
|
245
|
-
...resourceArtifact.materializedEntries!,
|
|
246
|
-
{
|
|
247
|
-
entryName: 'other/index.bin',
|
|
248
|
-
artifact: artifact('d'.repeat(64), 2),
|
|
249
|
-
},
|
|
250
|
-
],
|
|
251
|
-
}
|
|
252
|
-
: item
|
|
253
|
-
),
|
|
254
|
-
};
|
|
255
|
-
const { preparedPlanDigest: _preparedPlanDigest, ...digestInput } = tamperedWithoutDigest;
|
|
256
|
-
const tampered = {
|
|
257
|
-
...tamperedWithoutDigest,
|
|
258
|
-
preparedPlanDigest: digestFirmwareUpdateContract(digestInput),
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
expect(() => validateFirmwareUpdatePreparedPlan(tampered)).toThrow('duplicate entry names');
|
|
262
|
-
});
|
|
263
|
-
|
|
264
212
|
test('rejects unknown fields even when a caller presents a plan-shaped object', () => {
|
|
265
213
|
const plan = buildPlan();
|
|
266
214
|
expect(() =>
|