mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-29 15:50:28 +01:00
7086494b72
* updated snap permission to wallet_snap, updated tests and added migration * updated snap packages * yarn.lock fix * fixed errors * override policy * update policy * undo override * updated localization message descriptions * updated lavamoat policy * more policy updates * update permission controller version * update policy * update fixture builder * updated code to include permission value to satisfy wallet_snap permission description call * fix import issue * update test-snaps version * added missing actions, added snap permission dedupe function * prettier fix * fix fencing * add more fencing * prettier fix * fix fencing (again) * added new action and selector and updated view snap accordingly * update test snaps website version * unfence request variable * add fencing * add optional chaining to fix type error * update migration # * remove old migration * prettier fix * fix migration test * fix fencing * added missing fencing * updated code to workaround fencing * update test-snaps site version and remove snap confirm test * update snap packages * update policies * fix merge marker issue * update test * more fixes * fix permissions * update test * fixed test * Bump test-snaps and iframe-execution-environment * remove unused snap permission from fixture builder * update policies * undo comment removal, update selector implementation * removed unnecessary function, updated migration, updated caveat action * remove optional chaining * fix type issue * more type fixes * fix migration test * remove isFlask check, make migration logic more robust * update coverage * Update LavaMoat policies * Update test/e2e/snaps/enums.js * add extra bail condition * Revert "add extra bail condition" This reverts commit b45c53dcfc6e6e35a5e283d4955d6d6ea9ca5965. * Revert "Revert "add extra bail condition"" This reverts commit cd2ded677935c9cdab0c02b6af55474c83727f60. * fix test * add SnapController entry to state object * updated permission name and caveat type with hardcoded values * add extra test for non-flask scenario * update lavamoat policies * fix locale messages * change coverage target * re-enable rpc snap test * revert locale message change * fix el message * reverted changes --------- Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com>
141 lines
4.5 KiB
TypeScript
141 lines
4.5 KiB
TypeScript
import { cloneDeep, isArray } from 'lodash';
|
|
import { hasProperty, isObject } from '@metamask/utils';
|
|
|
|
export const version = 81;
|
|
|
|
/**
|
|
* Prior to this migration, snap <> dapp permissions were wildcards i.e. `wallet_snap_*`.
|
|
* Now the permission has been changed to `wallet_snap` and the current snap permissions
|
|
* that are under wildcards will be added as caveats to a parent `wallet_snap` permission.
|
|
*
|
|
* @param originalVersionedData - Versioned MetaMask extension state, exactly what we persist to dist.
|
|
* @param originalVersionedData.meta - State metadata.
|
|
* @param originalVersionedData.meta.version - The current state version.
|
|
* @param originalVersionedData.data - The persisted MetaMask state, keyed by controller.
|
|
* @returns Updated versioned MetaMask extension state.
|
|
*/
|
|
export async function migrate(originalVersionedData: {
|
|
meta: { version: number };
|
|
data: Record<string, unknown>;
|
|
}) {
|
|
const versionedData = cloneDeep(originalVersionedData);
|
|
versionedData.meta.version = version;
|
|
const state = versionedData.data;
|
|
const newState = transformState(state);
|
|
versionedData.data = newState;
|
|
return versionedData;
|
|
}
|
|
|
|
// We return state AS IS if there is any corruption
|
|
function transformState(state: Record<string, unknown>) {
|
|
if (
|
|
!hasProperty(state, 'SnapController') ||
|
|
!hasProperty(state, 'PermissionController') ||
|
|
!isObject(state.PermissionController)
|
|
) {
|
|
return state;
|
|
}
|
|
const { PermissionController } = state;
|
|
|
|
const { subjects } = PermissionController;
|
|
|
|
if (!isObject(subjects)) {
|
|
return state;
|
|
}
|
|
|
|
const snapPrefix = 'wallet_snap_';
|
|
|
|
for (const [subjectName, subject] of Object.entries(subjects)) {
|
|
if (!isObject(subject) || !isObject(subject.permissions)) {
|
|
return state;
|
|
}
|
|
// We keep track of the latest permission's date and associated id
|
|
// to assign to the wallet_snap permission after iterating through all permissions
|
|
let date = 1;
|
|
let id;
|
|
const { permissions } = subject;
|
|
// New permissions object that we use to tack on the `wallet_snap` permission
|
|
const updatedPermissions = { ...permissions };
|
|
for (const [permissionName, permission] of Object.entries(permissions)) {
|
|
// check if the permission is namespaced
|
|
if (permissionName.startsWith(snapPrefix)) {
|
|
if (
|
|
!isObject(permission) ||
|
|
!hasProperty(permission, 'id') ||
|
|
!hasProperty(permission, 'date')
|
|
) {
|
|
return state;
|
|
}
|
|
// We create a wallet_snap key if we already don't have one
|
|
if (!hasProperty(updatedPermissions, 'wallet_snap')) {
|
|
updatedPermissions.wallet_snap = {
|
|
caveats: [{ type: 'snapIds', value: {} }],
|
|
invoker: subjectName,
|
|
parentCapability: 'wallet_snap',
|
|
};
|
|
}
|
|
|
|
// Check if the existing permission is valid
|
|
if (!isObject(updatedPermissions.wallet_snap)) {
|
|
return state;
|
|
}
|
|
|
|
if (
|
|
!isArray(
|
|
(updatedPermissions.wallet_snap as Record<string, unknown>).caveats,
|
|
)
|
|
) {
|
|
return state;
|
|
}
|
|
|
|
// Adding the snap name to the wallet_snap permission's caveat value
|
|
const snapId = permissionName.slice(snapPrefix.length);
|
|
const caveat = (
|
|
(updatedPermissions.wallet_snap as Record<string, any>)
|
|
.caveats as unknown[]
|
|
)[0];
|
|
|
|
if (!isObject(caveat)) {
|
|
return state;
|
|
}
|
|
|
|
if (
|
|
!hasProperty(caveat, 'type') ||
|
|
caveat.type !== 'snapIds' ||
|
|
!hasProperty(caveat, 'value') ||
|
|
!isObject(caveat.value)
|
|
) {
|
|
return state;
|
|
}
|
|
caveat.value[snapId] = {};
|
|
|
|
if (
|
|
typeof permission.date !== 'number' ||
|
|
typeof permission.id !== 'string'
|
|
) {
|
|
return state;
|
|
}
|
|
|
|
// updating the date & id as we iterate through all permissions
|
|
if (permission.date > date) {
|
|
date = permission.date;
|
|
id = permission.id;
|
|
}
|
|
|
|
// finally deleting the stale permission
|
|
delete updatedPermissions[permissionName];
|
|
}
|
|
}
|
|
|
|
// we reassign the date and id here after iterating through all permissions
|
|
// and update the subject with the updated permissions
|
|
if (updatedPermissions.wallet_snap) {
|
|
(updatedPermissions.wallet_snap as Record<string, unknown>).date = date;
|
|
(updatedPermissions.wallet_snap as Record<string, unknown>).id = id;
|
|
subject.permissions = updatedPermissions;
|
|
}
|
|
}
|
|
|
|
return state;
|
|
}
|