Sfoglia il codice sorgente

feat: pinia persist plugin custom serializer (#3244)

Kirk Lin 1 anno fa
parent
commit
ea51c492c2

+ 1 - 1
src/settings/encryptionSetting.ts

@@ -10,4 +10,4 @@ export const cacheCipher = {
 };
 
 // Whether the system cache is encrypted using aes
-export const enableStorageEncryption = !isDevMode();
+export const SHOULD_ENABLE_STORAGE_ENCRYPTION = !isDevMode();

+ 39 - 2
src/store/plugin/persist.ts

@@ -5,13 +5,49 @@
  *
  */
 import type { Pinia } from 'pinia';
-import { createPersistedState } from 'pinia-plugin-persistedstate';
+import { createPersistedState, Serializer } from 'pinia-plugin-persistedstate';
 import type { PersistedStateFactoryOptions } from 'pinia-plugin-persistedstate';
 import { getCommonStoragePrefix } from '@/utils/env';
+import { Encryption, EncryptionFactory } from '@/utils/cipher';
+import { cacheCipher, SHOULD_ENABLE_STORAGE_ENCRYPTION } from '@/settings/encryptionSetting';
 
 export const PERSIST_KEY_PREFIX = getCommonStoragePrefix();
 
-// TODO customSerializer
+const persistEncryption: Encryption = EncryptionFactory.createAesEncryption({
+  key: cacheCipher.key,
+  iv: cacheCipher.iv,
+});
+
+/**
+ * Custom serializer for serialization and deserialization of storage data
+ * 自定义序列化器,用于序列化和反序列化存储数据
+ *
+ * @param shouldEnableEncryption whether to enable encryption for storage data 是否启用存储数据加密
+ * @returns serializer
+ */
+function customSerializer(shouldEnableEncryption: boolean): Serializer {
+  if (shouldEnableEncryption) {
+    return {
+      deserialize: (value) => {
+        const decrypted = persistEncryption.decrypt(value);
+        return JSON.parse(decrypted);
+      },
+      serialize: (value) => {
+        const serialized = JSON.stringify(value);
+        return persistEncryption.encrypt(serialized);
+      },
+    };
+  } else {
+    return {
+      deserialize: (value) => {
+        return JSON.parse(value);
+      },
+      serialize: (value) => {
+        return JSON.stringify(value);
+      },
+    };
+  }
+}
 
 /**
  * Register Pinia Persist Plugin
@@ -34,5 +70,6 @@ export function createPersistedStateOptions(keyPrefix: string): PersistedStateFa
   return {
     storage: localStorage,
     key: (id) => `${keyPrefix}__${id}`,
+    serializer: customSerializer(SHOULD_ENABLE_STORAGE_ENCRYPTION),
   };
 }

+ 5 - 2
src/utils/cache/index.ts

@@ -1,13 +1,16 @@
 import { getStorageShortName } from '/@/utils/env';
 import { createStorage as create, CreateStorageParams } from './storageCache';
-import { enableStorageEncryption, DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting';
+import {
+  SHOULD_ENABLE_STORAGE_ENCRYPTION,
+  DEFAULT_CACHE_TIME,
+} from '/@/settings/encryptionSetting';
 
 export type Options = Partial<CreateStorageParams>;
 
 const createOptions = (storage: Storage, options: Options = {}): Options => {
   return {
     // No encryption in debug mode
-    hasEncrypt: enableStorageEncryption,
+    hasEncrypt: SHOULD_ENABLE_STORAGE_ENCRYPTION,
     storage,
     prefixKey: getStorageShortName(),
     ...options,

+ 1 - 0
src/utils/cache/storageCache.ts

@@ -9,6 +9,7 @@ export interface CreateStorageParams extends EncryptionParams {
   hasEncrypt: boolean;
   timeout?: Nullable<number>;
 }
+// TODO 移除此文件夹下全部代码
 export const createStorage = ({
   prefixKey = '',
   storage = sessionStorage,