@metamask/snaps-controllers 17.1.1 → 17.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [17.1.2]
11
+
12
+ ### Fixed
13
+
14
+ - Detect and recover missing permissions for preinstalled Snaps ([#3775](https://github.com/MetaMask/snaps/pull/3775))
15
+
10
16
  ## [17.1.1]
11
17
 
12
18
  ### Fixed
@@ -990,7 +996,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
990
996
  - The version of the package no longer needs to match the version of all other
991
997
  MetaMask Snaps packages.
992
998
 
993
- [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@17.1.1...HEAD
999
+ [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@17.1.2...HEAD
1000
+ [17.1.2]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@17.1.1...@metamask/snaps-controllers@17.1.2
994
1001
  [17.1.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@17.1.0...@metamask/snaps-controllers@17.1.1
995
1002
  [17.1.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@17.0.0...@metamask/snaps-controllers@17.1.0
996
1003
  [17.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@16.1.1...@metamask/snaps-controllers@17.0.0
@@ -367,6 +367,38 @@ class SnapController extends base_controller_1.BaseController {
367
367
  this.messenger.publish('SnapController:snapInstalled', this.getTruncatedExpect(snapId), constants_1.METAMASK_ORIGIN, true);
368
368
  }
369
369
  }
370
+ // Ensure all preinstalled Snaps have their expected permissions.
371
+ for (const snap of Object.values(this.state.snaps).filter(({ preinstalled }) => preinstalled)) {
372
+ const processedPermissions = (0, snaps_rpc_methods_1.processSnapPermissions)(snap.manifest.initialPermissions);
373
+ this.#validateSnapPermissions(processedPermissions);
374
+ const { newPermissions, unusedPermissions } = this.#calculatePermissionsChange(snap.id, processedPermissions);
375
+ if ((0, utils_1.isNonEmptyArray)(Object.keys(newPermissions)) ||
376
+ (0, utils_1.isNonEmptyArray)(Object.keys(unusedPermissions))) {
377
+ const { proposedName } = (0, snaps_utils_1.getLocalizedSnapManifest)(snap.manifest, 'en', snap.localizationFiles ?? []);
378
+ // Recover the SVG icon from the constructor argument.
379
+ // Theoretically this may be out of date, but this is the best we can do.
380
+ const preinstalledSnap = preinstalledSnaps.find((potentialSnap) => potentialSnap.snapId === snap.id);
381
+ const { iconPath } = snap.manifest.source.location.npm;
382
+ const svgIcon = iconPath && preinstalledSnap
383
+ ? preinstalledSnap.files.find((file) => file.path === iconPath)
384
+ : undefined;
385
+ // If the permissions are out of sync, it is possible that the SubjectMetadataController also is.
386
+ this.messenger.call('SubjectMetadataController:addSubjectMetadata', {
387
+ subjectType: permission_controller_1.SubjectType.Snap,
388
+ name: proposedName,
389
+ origin: snap.id,
390
+ version: snap.version,
391
+ svgIcon: svgIcon ? new snaps_utils_1.VirtualFile(svgIcon).toString() : null,
392
+ });
393
+ this.#updatePermissions({
394
+ snapId: snap.id,
395
+ newPermissions,
396
+ unusedPermissions,
397
+ });
398
+ (0, snaps_utils_1.logWarning)(`The permissions for "${snap.id}" were out of sync and have been automatically restored. If you see this message, please file a bug report.`);
399
+ this.messenger.captureException?.(new Error(`The permissions for "${snap.id}" were out of sync and have been automatically restored. This could indicate persistence issues.`));
400
+ }
401
+ }
370
402
  }
371
403
  #pollForLastRequestStatus() {
372
404
  this.#timeoutForLastRequestStatus = setTimeout(() => {