-
Notifications
You must be signed in to change notification settings - Fork 7.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: the cache can be configured to be encrypted
- Loading branch information
Showing
20 changed files
with
300 additions
and
185 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
## Wip | ||
|
||
### ✨ Features | ||
|
||
- 缓存可以配置是否加密 | ||
- 多语言支持 | ||
|
||
### 🎫 Chores | ||
|
||
- 移除 messageSetting 配置 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
import AppLocalPicker from './src/AppLocalPicker.vue'; | ||
import AppFooterToolbar from './src/AppFooterToolbar.vue'; | ||
import { withInstall } from '../util'; | ||
|
||
export { AppLocalPicker }; | ||
export { AppLocalPicker, AppFooterToolbar }; | ||
|
||
export default withInstall(AppLocalPicker, AppFooterToolbar); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,7 @@ | ||
import type { App } from 'vue'; | ||
import Authority from './src/index.vue'; | ||
|
||
export default (app: App): void => { | ||
app.component(Authority.name, Authority); | ||
}; | ||
import { withInstall } from '../util'; | ||
|
||
export default withInstall(Authority); | ||
|
||
export { Authority }; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { isDevMode } from '/@/utils/env'; | ||
|
||
// System default cache time, in seconds | ||
export const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7; | ||
|
||
// aes encryption key | ||
export const cacheCipher = { | ||
key: '_12345678901234@', | ||
iv: '@12345678901234_', | ||
}; | ||
|
||
// Whether the system cache is encrypted using aes | ||
export const enableStorageEncryption = !isDevMode(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { DEFAULT_CACHE_TIME } from '../../settings/encryptionSetting'; | ||
import { getStorageShortName } from '/@/utils/helper/envHelper'; | ||
import { cacheCipher } from '/@/settings/encryptionSetting'; | ||
import Encryption from '/@/utils/encryption/aesEncryption'; | ||
|
||
export default class WebCookie { | ||
private encryption: Encryption; | ||
private hasEncrypt: boolean; | ||
|
||
constructor(hasEncrypt = true, key = cacheCipher.key, iv = cacheCipher.iv) { | ||
const encryption = new Encryption({ key, iv }); | ||
this.encryption = encryption; | ||
this.hasEncrypt = hasEncrypt; | ||
} | ||
|
||
private getKey(key: string) { | ||
return `${getStorageShortName()}${key}`.toUpperCase(); | ||
} | ||
|
||
/** | ||
* Add cookie | ||
* @param name cookie key | ||
* @param value cookie value | ||
* @param expire | ||
* If the expiration time is not set, the default management browser will automatically delete | ||
* e.g: | ||
* cookieData.set('name','value',) | ||
*/ | ||
setCookie(key: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) { | ||
value = this.hasEncrypt ? this.encryption.encryptByAES(JSON.stringify(value)) : value; | ||
document.cookie = this.getKey(key) + '=' + value + '; Max-Age=' + expire; | ||
} | ||
|
||
/** | ||
* Get the cook value according to the key | ||
* @param key cookie key | ||
*/ | ||
getCookie(key: string) { | ||
const arr = document.cookie.split('; '); | ||
for (let i = 0; i < arr.length; i++) { | ||
const arr2 = arr[i].split('='); | ||
if (arr2[0] === this.getKey(key)) { | ||
let message: any = null; | ||
const str = arr2[1]; | ||
if (this.hasEncrypt && str) { | ||
message = this.encryption.decryptByAES(str); | ||
try { | ||
return JSON.parse(message); | ||
} catch (e) { | ||
return str; | ||
} | ||
} | ||
return str; | ||
} | ||
} | ||
return ''; | ||
} | ||
|
||
/** | ||
* Delete cookie based on cookie key | ||
* @param key cookie key | ||
*/ | ||
removeCookie(key: string) { | ||
this.setCookie(key, 1, -1); | ||
} | ||
|
||
/** | ||
* clear cookie | ||
*/ | ||
clearCookie(): void { | ||
const keys = document.cookie.match(/[^ =;]+(?==)/g); | ||
if (keys) { | ||
for (let i = keys.length; i--; ) { | ||
document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString(); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,20 @@ | ||
import { getStorageShortName } from '/@/utils/helper/envHelper'; | ||
import { createStorage as create } from './Storage'; | ||
|
||
// debug模式下不加密 | ||
import { createStorage as create } from './storageCache'; | ||
import { enableStorageEncryption } from '/@/settings/encryptionSetting'; | ||
|
||
const createOptions = (storage = sessionStorage) => { | ||
return { | ||
// No encryption in debug mode | ||
hasEncrypt: enableStorageEncryption, | ||
storage, | ||
prefixKey: getStorageShortName(), | ||
}; | ||
}; | ||
|
||
export const WebStorage = create(createOptions()); | ||
|
||
export const createStorage = (storage: Storage = sessionStorage) => { | ||
return create(createOptions(storage))!; | ||
}; | ||
|
||
export default WebStorage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting'; | ||
import { cacheCipher } from '/@/settings/encryptionSetting'; | ||
import Encryption, { EncryptionParams } from '/@/utils/encryption/aesEncryption'; | ||
|
||
export interface CreateStorageParams extends EncryptionParams { | ||
storage: Storage; | ||
|
||
hasEncrypt: boolean; | ||
} | ||
export const createStorage = ({ | ||
prefixKey = '', | ||
storage = sessionStorage, | ||
key = cacheCipher.key, | ||
iv = cacheCipher.iv, | ||
hasEncrypt = true, | ||
} = {}) => { | ||
if (hasEncrypt && [key.length, iv.length].some((item) => item !== 16)) { | ||
throw new Error('When hasEncrypt is true, the key or iv must be 16 bits!'); | ||
} | ||
|
||
const encryption = new Encryption({ key, iv }); | ||
|
||
/** | ||
*Cache class | ||
*Construction parameters can be passed into sessionStorage, localStorage, | ||
* @class Cache | ||
* @example | ||
*/ | ||
const WebStorage = class WebStorage { | ||
private storage: Storage; | ||
private prefixKey?: string; | ||
private encryption: Encryption; | ||
private hasEncrypt: boolean; | ||
/** | ||
* | ||
* @param {*} storage | ||
*/ | ||
constructor() { | ||
this.storage = storage; | ||
this.prefixKey = prefixKey; | ||
this.encryption = encryption; | ||
this.hasEncrypt = hasEncrypt; | ||
} | ||
|
||
private getKey(key: string) { | ||
return `${this.prefixKey}${key}`.toUpperCase(); | ||
} | ||
|
||
/** | ||
* | ||
* Set cache | ||
* @param {string} key | ||
* @param {*} value | ||
* @expire Expiration time in seconds | ||
* @memberof Cache | ||
*/ | ||
set(key: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) { | ||
const stringData = JSON.stringify({ | ||
value, | ||
expire: expire !== null ? new Date().getTime() + expire * 1000 : null, | ||
}); | ||
const stringifyValue = this.hasEncrypt | ||
? this.encryption.encryptByAES(stringData) | ||
: stringData; | ||
this.storage.setItem(this.getKey(key), stringifyValue); | ||
} | ||
|
||
/** | ||
*Read cache | ||
* @param {string} key | ||
* @memberof Cache | ||
*/ | ||
get(key: string, def: any = null): any { | ||
const item = this.storage.getItem(this.getKey(key)); | ||
if (item) { | ||
try { | ||
const decItem = this.hasEncrypt ? this.encryption.decryptByAES(item) : item; | ||
const data = JSON.parse(decItem); | ||
const { value, expire } = data; | ||
if (expire === null || expire >= new Date().getTime()) { | ||
return value; | ||
} | ||
this.remove(this.getKey(key)); | ||
} catch (e) { | ||
return def; | ||
} | ||
} | ||
return def; | ||
} | ||
|
||
/** | ||
* Delete cache based on key | ||
* @param {string} key | ||
* @memberof Cache | ||
*/ | ||
remove(key: string) { | ||
this.storage.removeItem(this.getKey(key)); | ||
} | ||
|
||
/** | ||
* Delete all caches of this instance | ||
*/ | ||
clear(): void { | ||
this.storage.clear(); | ||
} | ||
}; | ||
return new WebStorage(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import CryptoES from 'crypto-es'; | ||
export interface EncryptionParams { | ||
key: string; | ||
iv: string; | ||
} | ||
export class Encryption { | ||
private key; | ||
|
||
private iv; | ||
|
||
constructor(opt: EncryptionParams) { | ||
const { key, iv } = opt; | ||
this.key = CryptoES.enc.Utf8.parse(key); | ||
this.iv = CryptoES.enc.Utf8.parse(iv); | ||
} | ||
|
||
get getOpt(): CryptoES.lib.CipherCfg { | ||
return { | ||
mode: CryptoES.mode.CBC as any, | ||
padding: CryptoES.pad.Pkcs7, | ||
iv: this.iv, | ||
}; | ||
} | ||
|
||
encryptByAES(str: string) { | ||
const encrypted = CryptoES.AES.encrypt(str, this.key, this.getOpt); | ||
return encrypted.toString(); | ||
} | ||
|
||
decryptByAES(str: string) { | ||
const decrypted = CryptoES.AES.decrypt(str, this.key, this.getOpt); | ||
return decrypted.toString(CryptoES.enc.Utf8); | ||
} | ||
} | ||
export default Encryption; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.