1 import { isB2BAdmin } from '@proton/pass/lib/organization/helpers';
2 import { type MaybeNull } from '@proton/pass/types';
3 import { type XorObfuscation, obfuscate } from '@proton/pass/utils/obfuscate/xor';
4 import { objectFilter } from '@proton/pass/utils/object/filter';
5 import { objectMap } from '@proton/pass/utils/object/map';
6 import type { Organization } from '@proton/shared/lib/interfaces';
8 import { unwrapOptimisticState } from './optimistic/utils/transformers';
9 import { INITIAL_ORGANIZATION_SETTINGS } from './reducers/organization';
10 import { INITIAL_HIGHSECURITY_SETTINGS } from './reducers/user';
11 import { selectLoginItems, selectPassPlan, selectUser } from './selectors';
12 import type { State } from './types';
14 export const migrate = (state: State) => {
15 const user = selectUser(state);
16 const plan = selectPassPlan(state);
18 /** Sanity migration :
19 * Sanitize the item state to ensure we have no invalid item
20 * data - FIXME: remove when pin-pointing the faulty partial
21 * item update causing this edge-case error */
22 state.items.byShareId = {
23 ...state.items.byShareId,
24 ...objectMap(unwrapOptimisticState(state.items.byShareId), (_, items) =>
25 objectFilter(items, (_, item) => item && ['itemId', 'shareId', 'data'].every((key) => key in item))
29 /** v1.13.0 migration */
30 if ('organization' in state.user) {
31 const organization = state.user.organization as MaybeNull<Organization>;
32 delete state.user.organization;
34 if (!state.organization) {
35 state.organization = organization
38 canUpdate: user ? isB2BAdmin(user, plan) : false,
39 settings: INITIAL_ORGANIZATION_SETTINGS,
45 /** v1.17.2 migration */
46 if (state.user.userSettings && !state.user.userSettings.HighSecurity) {
47 state.user.userSettings.HighSecurity = INITIAL_HIGHSECURITY_SETTINGS;
50 /** v1.20.0 migration */
51 selectLoginItems(state).forEach(({ data: { content: item } }) => {
52 if ('username' in item) {
53 item.itemEmail = item.username as XorObfuscation;
54 item.itemUsername = obfuscate('');
59 /** v1.23.0 migration */
60 if (!state.user.userData) {
61 state.user.userData = {
63 aliasSyncEnabled: false,
64 pendingAliasToSync: 0,
69 if (!state.user.devices) state.user.devices = [];