permission.ts raw

   1  import {
   2    Permission_DECRYPTED,
   3    Permission_ENCRYPTED,
   4    StorageService,
   5  } from '@common';
   6  import { LockedVaultContext } from './identity';
   7  
   8  export const deletePermission = async function (
   9    this: StorageService,
  10    permissionId: string
  11  ): Promise<void> {
  12    this.assureIsInitialized();
  13  
  14    const browserSessionData = this.getBrowserSessionHandler().browserSessionData;
  15    const browserSyncData = this.getBrowserSyncHandler().browserSyncData;
  16    if (!browserSessionData || !browserSyncData) {
  17      throw new Error('Browser session or sync data is undefined.');
  18    }
  19  
  20    browserSessionData.permissions = browserSessionData.permissions.filter(
  21      (x) => x.id !== permissionId
  22    );
  23    await this.getBrowserSessionHandler().saveFullData(browserSessionData);
  24  
  25    const encryptedPermissionId = await this.encrypt(permissionId);
  26    await this.getBrowserSyncHandler().saveAndSetPartialData_Permissions({
  27      permissions: browserSyncData.permissions.filter(
  28        (x) => x.id !== encryptedPermissionId
  29      ),
  30    });
  31  };
  32  
  33  export const decryptPermission = async function (
  34    this: StorageService,
  35    permission: Permission_ENCRYPTED,
  36    withLockedVault: LockedVaultContext | undefined = undefined
  37  ): Promise<Permission_DECRYPTED> {
  38    if (typeof withLockedVault === 'undefined') {
  39      const decryptedPermission: Permission_DECRYPTED = {
  40        id: await this.decrypt(permission.id, 'string'),
  41        identityId: await this.decrypt(permission.identityId, 'string'),
  42        method: await this.decrypt(permission.method, 'string'),
  43        methodPolicy: await this.decrypt(permission.methodPolicy, 'string'),
  44        host: await this.decrypt(permission.host, 'string'),
  45      };
  46      if (permission.kind) {
  47        decryptedPermission.kind = await this.decrypt(permission.kind, 'number');
  48      }
  49      return decryptedPermission;
  50    }
  51  
  52    // v2: Use pre-derived key
  53    if (withLockedVault.keyBase64) {
  54      const decryptedPermission: Permission_DECRYPTED = {
  55        id: await this.decryptWithLockedVaultV2(
  56          permission.id,
  57          'string',
  58          withLockedVault.iv,
  59          withLockedVault.keyBase64
  60        ),
  61        identityId: await this.decryptWithLockedVaultV2(
  62          permission.identityId,
  63          'string',
  64          withLockedVault.iv,
  65          withLockedVault.keyBase64
  66        ),
  67        method: await this.decryptWithLockedVaultV2(
  68          permission.method,
  69          'string',
  70          withLockedVault.iv,
  71          withLockedVault.keyBase64
  72        ),
  73        methodPolicy: await this.decryptWithLockedVaultV2(
  74          permission.methodPolicy,
  75          'string',
  76          withLockedVault.iv,
  77          withLockedVault.keyBase64
  78        ),
  79        host: await this.decryptWithLockedVaultV2(
  80          permission.host,
  81          'string',
  82          withLockedVault.iv,
  83          withLockedVault.keyBase64
  84        ),
  85      };
  86      if (permission.kind) {
  87        decryptedPermission.kind = await this.decryptWithLockedVaultV2(
  88          permission.kind,
  89          'number',
  90          withLockedVault.iv,
  91          withLockedVault.keyBase64
  92        );
  93      }
  94      return decryptedPermission;
  95    }
  96  
  97    // v1: Use password (PBKDF2)
  98    const decryptedPermission: Permission_DECRYPTED = {
  99      id: await this.decryptWithLockedVault(
 100        permission.id,
 101        'string',
 102        withLockedVault.iv,
 103        withLockedVault.password!
 104      ),
 105      identityId: await this.decryptWithLockedVault(
 106        permission.identityId,
 107        'string',
 108        withLockedVault.iv,
 109        withLockedVault.password!
 110      ),
 111      method: await this.decryptWithLockedVault(
 112        permission.method,
 113        'string',
 114        withLockedVault.iv,
 115        withLockedVault.password!
 116      ),
 117      methodPolicy: await this.decryptWithLockedVault(
 118        permission.methodPolicy,
 119        'string',
 120        withLockedVault.iv,
 121        withLockedVault.password!
 122      ),
 123      host: await this.decryptWithLockedVault(
 124        permission.host,
 125        'string',
 126        withLockedVault.iv,
 127        withLockedVault.password!
 128      ),
 129    };
 130    if (permission.kind) {
 131      decryptedPermission.kind = await this.decryptWithLockedVault(
 132        permission.kind,
 133        'number',
 134        withLockedVault.iv,
 135        withLockedVault.password!
 136      );
 137    }
 138    return decryptedPermission;
 139  };
 140  
 141  export const decryptPermissions = async function (
 142    this: StorageService,
 143    permissions: Permission_ENCRYPTED[],
 144    withLockedVault: LockedVaultContext | undefined = undefined
 145  ): Promise<Permission_DECRYPTED[]> {
 146    const decryptedPermissions: Permission_DECRYPTED[] = [];
 147  
 148    for (const permission of permissions) {
 149      try {
 150        const decryptedPermission = await decryptPermission.call(
 151          this,
 152          permission,
 153          withLockedVault
 154        );
 155        decryptedPermissions.push(decryptedPermission);
 156      } catch (error) {
 157        // Skip corrupted permissions (e.g., encrypted with wrong key)
 158        console.warn('[vault] Skipping corrupted permission:', error);
 159      }
 160    }
 161  
 162    return decryptedPermissions;
 163  };
 164