diff --git a/.eslintrc.json b/.eslintrc.json index 3db1e06..a231f47 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,7 +8,6 @@ "extends": [ "airbnb-base", "plugin:@typescript-eslint/recommended", - "prettier/@typescript-eslint", "plugin:prettier/recommended", "prettier" ], diff --git a/README.md b/README.md index bef5815..d819478 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,22 @@ # Encrypt Storage ![npm](https://img.shields.io/npm/dm/encrypt-storage) [![Code Size](https://img.shields.io/github/languages/code-size/michelonsouza/encrypt-storage)](https://github.com/michelonsouza/encrypt-storage) [![Version](https://img.shields.io/github/package-json/v/michelonsouza/encrypt-storage/master)](https://github.com/michelonsouza/encrypt-storage/blob/master/package.json) [![Build Status](https://travis-ci.com/michelonsouza/encrypt-storage.svg?branch=master)](https://travis-ci.com/michelonsouza/encrypt-storage) [![Coverage Status](https://coveralls.io/repos/github/michelonsouza/encrypt-storage/badge.svg)](https://coveralls.io/github/michelonsouza/encrypt-storage) +OBS: This is the new version of Encrypt Storage, it has braking changes that will not be described below. For version `1.3.X` documentation, access this [link](./docs/README_V1.md). + The `Encrypt Storage` is a `wrapper` for native `Storage` of browser. Using the `crypto-js` library as an encryption engine, it saves the encrypted data on the `selected storage` in the same way as the native `Storage`. > NOTE: Nothing on the front end is entirely secure. The library's proposal is to make it difficult for the user to see the data through the console, but as the secret key is on the front end, if the user searches hard enough, he will end up finding it. Just to make it clear that nothing is completely secure on the front end. Thank you for your attention. -## Table of Contents - -- [Encrypt Storage](#encrypt-storage) - - [Table of Contents](#table-of-contents) - - [Features](#features) - - [Installing](#installing) - - [Examples](#examples) - - [CommonJS](#commonjs) - - [JS Import (es6)](#js-import-es6) - - [Conventions](#conventions) - - [Parameters](#parameters) - - [secretKey](#secretkey) - - [options](#options) - - [Global state management persist solutions](#global-state-management-persist-solutions) - - [redux-persist](#redux-persist) - - [vuex-persist](#vuex-persist) - - [AWS Amplify](#aws-amplify) - - [Usage](#usage) - - [setItem](#setitem) - - [getItem](#getitem) - - [removeItem](#removeitem) - - [removeItemFromPattern](#removeitemfrompattern) - - [clear](#clear) - - [key](#key) - - [length](#length) - - [encryptString](#encryptstring) - - [decryptString](#decryptstring) -- [License](#license) +[TOC] ## Features - Save encrypted data in `localStorage` and `sessionStorage` - - Recover encrypted data - - Use in the same way as native Storage - - Use with `stateManagement` persisters (`vuex-persist` and `redux-persist`) + - Recover encrypted data with `get` functions + - Use in the same way as native `Web Storage` (localStorage and sessionStorage) + - If you use the `stateManagementUse` option, the data acquired in `get` functions will `not` have their return transformed into `Javascript objects`. + - Use with `stateManagement` persisters (`vuex-persist` and `redux-persist`*) ## Installing @@ -58,228 +34,370 @@ Or yarn: $ yarn add encrypt-storage ``` -## Examples +## Options + +The `options` object is optional and consists of the following properties: + +|propertie |type |default | +|-------------------|-------------------------------------------|---------------| +|prefix |`string` |`''` | +|storageType |`localStorage` or `sessionStorage` |`localStorage` | +|stateManagementUse |`boolean` |`false` | +|encAlgorithm |`AES | Rabbit | RC4 | RC4Drop` |`AES` | + +## Usage + +### Conventions + +Create a `file` containing the `EncryptStorage` instance in a `utils` folder or folder of your choice. It is recommended to use it as a `singleton` for better use of the library. +> Directory Layout +``` +📦 src + ┣ 📂 utils + ┃ ┗ 📜 storage.ts + ┗ 📜 index.ts + ... +``` + +### Parameters + +*secretKey*: **required** = A string containing at least 10 characters; +**NOTE**: If you are using a `SPA` model (vue, react or angular) prefer to store this information in your application's `.env` file. + +*options*: **optional** = An object as described above and which will be shown below; ### CommonJS ```typescript const { EncryptStorage } = require('encrypt-storage'); -const encryptStorage = EncryptStorage('secret_key', options); +// Example of secret_key variable in an .env file +// const encryptStorage = new EncryptStorage(process.env.SECRET_KEY, options); +const encryptStorage = new EncryptStorage('secret-key', options); module.exports = encryptStorage ``` -### JS Import (es6) +### JS Import (ES6+) ```typescript import { EncryptStorage } from 'encrypt-storage'; -export const encryptStorage = EncryptStorage('secret_key', options); +export const encryptStorage = new EncryptStorage('secret-key', options); ``` -### Conventions -Create a file in your utils folder or a folder of your choice. But I advise you to use it as a singleton, so to speak, for better use. +### Options implementation -``` -📦 src - ┣ 📂 utils - ┃ ┗ 📜 index.ts - ┗ 📜 index.ts -``` +#### *prefix* -> Directory Layout +default `''` - is optional and is the prefix of all keys used in the selected storage as shown below: ```typescript -// const { EncryptStorage } = require('encrypt-storage'); +import { EncryptStorage } from 'encrypt-storage'; -export const encryptStorage = EncryptStorage('secret_key', options) +export const encryptStorage = new EncryptStorage('secret-key', { + prefix: '@example', +}); ``` -## Parameters +#### *storageType* -### secretKey - -The `secretKey` parameter is a `string` you encrypt your data. If you use a `framework` like `ReactJS` or `VueJS` prefer to store this data in your application's `.env` file: +default `localStorage` - is the type of storage that will be used, at the moment only `localStorage` and `sessionStorage` are allowed: ```typescript -// const { EncryptStorage } = require('encrypt-storage'); +import { EncryptStorage } from 'encrypt-storage'; -export const encryptStorage = EncryptStorage(process.env.SECRET_KEY, options) +export const encryptStorage = new EncryptStorage('secret-key', { + storageType: 'sessionStorage', +}); ``` -### options +#### *stateManagementUse* -The options object consists of the following properties: +default `false` - is a `boolean` value that, when true allows the use of it with `vuex-persist` and `redux-persist`: -|key |type |default | -|-------------------|-----------------------------------|---------------| -|prefix |`string` |`null` | -|storageType |`localStorage` or `sessionStorage` |`localStorage` | -|stateManagementUse |`boolean` |`false` | +```typescript +import { EncryptStorage } from 'encrypt-storage'; +export const encryptStorage = new EncryptStorage('secret-key', { + stateManagementUse: true, +}); +``` + +#### *encAlgorithm* -*prefix*: default `null` - is optional and is the prefix of all keys used in the selected storage as shown below: +default `AES` - Is the selected encryption algorithm.: ```typescript -//... -export const encryptStorage = EncryptStorage('secret_key', { - ..., - prefix: '@prefix' +import { EncryptStorage } from 'encrypt-storage'; + +export const encryptStorage = new EncryptStorage('secret-key', { + encAlgorithm: 'Rabbit', }); ``` -in your storage: +### Functions -![storageKeyValue](./docs/resources/storageKeyValue.png) +From here, we will have the following code as the EncryptStorage instance model: -## Global state management persist solutions +```typescript +import { EncryptStorage } from 'encrypt-storage'; -*stateManagementUse*: default `false` - is a `boolean` value that, when true allows the use of it with `vuex-persist` and `redux-persist`: +export const encryptStorage = new EncryptStorage('secret-key', { + prefix: '@example', +}); +``` -### redux-persist +#### *setItem* +Add `key` and `encrypted` value to selected `storage`. ```typescript -... -const persistConfig = { - key: 'root', - storage: encryptStorage, - whitelist: ['navigation'], - ... -}; +encryptStorage.setItem('token', 'edbe38e0-748a-49c8-9f8f-b68f38dbe5a2'); ``` -### vuex-persist +in your `storage`: + +|Key |Value | +|------------------|-------------------------------------------| +|`@example:token` |`U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw`... | + +#### *getItem* +Returns the value `decrypted` or `undefined` by the `key` passed by `parameter`. Default type is `any`; + +**NOTE**: It is possible to pass a `generics` (typescript case) to obtain a consistent and typed return for better use in the `typescript`. ```typescript -... -const vuexLocal = new VuexPersistence({ - storage: encryptStorage -}) +const value = encryptStorage.getItem('token'); +``` + +result of `getItem`: +```bash +'edbe38e0-748a-49c8-9f8f-b68f38dbe5a2' ``` -*storageType*: default `localStorage` - is the type of storage that will be used, at the moment only `localStorage` and` sessionStorage` are allowed: +#### *removeItem* +Remove item from selected `storage`. + +in your `storage`: + +|Key |Value | +|------------------|-------------------------------------------| +|`@example:token` |`U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw`... | ```typescript -//... -export const encryptStorage = EncryptStorage('secret_key', { - ..., - storageType: 'sessionStorage' -}); +encryptStorage.removeItem('token'); ``` -## AWS Amplify +now in your `storage`: -In the case of `aws-amplify`, if you want to use the facility of not needing to use `JSON.parse` in the rest of the application, prefer to create an instance within the `amplify` configuration file, as follows: +|Key |Value | +|------------------|-------------------------------------------| +|` ` |` ` | + +#### *getItemFromPattern* +Returns an `object` containing the `original` keys (no prefix) and `decrypted` values or `undefined` when no value found. + +in your `storage`: + +|Key |Value | +|-------------------------------|-------------------------------------------| +|`@example:fruit:apple` |`U2FsdGVkX1/2KEwOH+w4QaIc` | +|`@example:fruit:grape` |`U2FsdGVkX1/yq5521ZXB5pqw` | +|`@example:vegetable:lettuce` |`U2FsdGVkX1/tT67hnb*\afcb` | +|`@example:token` |`U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw`... | ```typescript -import Amplify from 'aws-amplify'; -import { EncryptStorage } from 'encrypt-storage'; +const values = encryptStorage.getItemFromPattern('fruit'); +``` -const encryptStorage = EncryptStorage('secret_key',{ - ..., - stateManagementUse: true, -}); +result of `getItemFromPattern`: +```typescript +const values = { + 'fruit:apple': 'apple', + 'fruit:grape': 'grape', +} +``` -... +#### *removeItemFromPattern* +Removes `all` items that have the `pattern` passed by `parameter` from the selected `storage`. -Amplify.configure({ - Auth: { - ..., - storage: encryptStorage, - }, -}); +in your `storage`: + +|Key |Value | +|-------------------------------|-------------------------------------------| +|`@example:fruit:apple` |`U2FsdGVkX1/2KEwOH+w4QaIc` | +|`@example:fruit:grape` |`U2FsdGVkX1/yq5521ZXB5pqw` | +|`@example:vegetable:lettuce` |`U2FsdGVkX1/tT67hnb*\afcb` | +|`@example:token` |`U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw`... | + +```typescript +encryptStorage.removeItemFromPattern('fruit'); ``` -## Usage -The usage follows the premise that encryptStorage has been "instantiated" in another file. In the example, the utils folder is used and JS imports. +now in your `storage`: + +|Key |Value | +|-------------------------------|-------------------------------------------| +|`@example:vegetable:lettuce` |`U2FsdGVkX1/tT67hnb*\afcb` | +|`@example:token` |`U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw`... | + +#### *key* +Returns the `key` corresponding to the `index` passed by `parameter` or `null`. + +in your `storage`: + +|Key |Value | +|-------------------------------|-------------------------------------------| +|`@example:vegetable:lettuce` |`U2FsdGVkX1/tT67hnb*\afcb` | +|`@example:token` |`U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw`... | -### setItem ```typescript -... -import { encryptStorage } from './utils'; +const key = encryptStorage.key(0); +``` -encryptStorage.setItem('user', { name: 'John', age: 36 }); +result of `key`: +```bash +'@example:vegetable:lettuce' ``` -### getItem -the getItem function is slightly different from the native api because it does not need to have its data treated, when the data exists, by JSON.parse as follows: + +#### *length* +Returns the `amount` of values from the selected `storage`. + +in your `storage`: + +|Key |Value | +|-------------------------------|-------------------------------------------| +|`@example:vegetable:lettuce` |`U2FsdGVkX1/tT67hnb*\afcb` | +|`@example:token` |`U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw`... | ```typescript -... -encryptStorage.setItem('user', { name: 'John', age: 36 }); -const decryptedData = encryptStorage.getItem('user'); +const length = encryptStorage.length; +``` -// { name: 'John', age: 36 } (is an object Javascript, not a string) +result of `length`: +```bash +2 ``` -### removeItem +#### *clear* +Removes `all` keys and values from the selected `storage`. + +in your `storage`: -Remove an item from `selectedStorage` +|Key |Value | +|-------------------------------|-------------------------------------------| +|`@example:vegetable:lettuce` |`U2FsdGVkX1/tT67hnb*\afcb` | +|`@example:token` |`U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw`... | ```typescript -... -encryptStorage.removeItem('user'); +encryptStorage.clear(); ``` -### removeItemFromPattern +now in your `storage`: -Remove an item from `selectedStorage` +|Key |Value | +|------------------|-------------------------------------------| +|` ` |` ` | -```typescript -... -encryptStorage.setItem('12345678:user', { id: 1234 }); -encryptStorage.setItem('12345678:item', { id: 5678 }); +#### *encryptString* +Encrypts a `string` passed by `parameter`. -encryptStorage.removeItemFromPattern('12345678'); +```typescript +const value = encryptStorage.encryptString('John Doe'); +``` -// items '12345678:user' and '12345678:item' are removed from 'selectedStorage' +result of `encryptString`: +```typescript +const value = 'U2FsdGVkX1/tT67hnb*\afcb'; ``` -### clear +#### *decryptString* +Decrypts a `string` passed by `parameter`. -Clear all data from `selectedStorage` +```typescript +const value = encryptStorage.decryptString('U2FsdGVkX1/tT67hnb*\afcb'); +``` +result of `decryptString`: ```typescript -... -encryptStorage.clear(); +const value = 'John Doe'; ``` -### key +### AsyncEncryptStorage + +EncryptStorage can also be used asynchronously, simply using its corresponding version already exported by the library. + +**NOTE**: This functionality has its usefulness revealed in the context of redux-persist, shown below. -Returns a key of `index` param or `null` if not exists +example: ```typescript -... -encryptStorage.key(0); +import { AsyncEncryptStorage } from 'encrypt-storage'; + +export const encryptStorage = new AsyncEncryptStorage('secret-key', options); + +async function getDecryptedValue('key'): Promise { + const value = await encryptStorage.getItem('key'); +} ``` -### length +### AWS Amplify -Returns a `quantity` of `keys` existents in `selectedStorage` +In the case of `aws-amplify`, if you want to use the facility of not needing to use `JSON.parse` in the rest of the application, prefer to create an instance within the `amplify` configuration file, as follows: ```typescript +import Amplify from 'aws-amplify'; +import { EncryptStorage } from 'encrypt-storage'; + +const encryptStorage = new EncryptStorage('secret_key', { + ..., + stateManagementUse: true, +}); + ... -encryptStorage.length; + +Amplify.configure({ + Auth: { + ..., + storage: encryptStorage, + }, +}); ``` -### encryptString -Encrypt any string and rerturn `encrypted value` +### State Management Persisters + +This library can be used to encrypt data from `state management persisters` like [vuex-persist](https://www.npmjs.com/package/vuex-persist) and [redux-persist](https://www.npmjs.com/package/redux-persist). Below are their respective implementations: + +**NOTE**: the `stateManagementUse` option must be used in the `EncryptStorage` instance to work `correctly`. + +#### *vuex-persist* + ```typescript -... -import { encryptStorage } from './utils'; +import VuexPersistence from 'vuex-persist'; -const encryptedValue = encryptStorage.encryptString('any_string'); -// 'U2FsdGVkX1/jvF6fLkGI3aALI9ssWNAPAeZ5nxeskh8=' +import { encryptStorage } from 'path/to/encryptStorage'; + +const vuexLocal = new VuexPersistence({ + storage: encryptStorage, +}); ``` -### decryptString -Decrypt any string (encrypted with `encryptString`) and return `decrypted value` +#### *redux-persist* + +**NOTE**: In the case of `redux-persist` it is `necessary` to use an `asynchronous` implementation, already provided by `EncryptStorage`. + ```typescript -... -import { encryptStorage } from './utils'; +// ... +import { AsyncEncryptStorage } from 'encrypt-storage'; + +export const encryptStorage = new AsyncEncryptStorage('secret-key', options); -const decryptedValue = encryptStorage.decryptString('U2FsdGVkX1/jvF6fLkGI3aALI9ssWNAPAeZ5nxeskh8='); -// 'any_string' +const persistConfig = { + key: 'root', + storage: encryptStorage, + whitelist: ['navigation'], + ... +}; ``` # License diff --git a/__tests__/encrypt-storage.spec.ts b/__tests__/encrypt-storage.spec.ts index 4d7c157..49bee9e 100644 --- a/__tests__/encrypt-storage.spec.ts +++ b/__tests__/encrypt-storage.spec.ts @@ -127,6 +127,30 @@ describe('EncryptStorage', () => { expect(storagedValue).toEqual(mockedValue); }); + it('should calls localStorage.getItem for all items with this pattern and remove prefix key', () => { + const prefix = faker.random.word(); + const safeStorage = makeSut({ + prefix, + }); + const pattern = faker.random.alphaNumeric(8); + const userKey = `${pattern}:user`; + const itemKey = `${pattern}:item`; + + const mockedValue = { + [userKey]: { id: faker.datatype.number(1000) }, + [itemKey]: { id: faker.datatype.number(1000) }, + }; + + safeStorage.setItem(userKey, mockedValue[userKey]); + safeStorage.setItem(itemKey, mockedValue[itemKey]); + + const storagedValue = safeStorage.getItemFromPattern(pattern); + + expect(localStorage.getItem).toHaveBeenCalledWith(`${prefix}:${userKey}`); + expect(localStorage.getItem).toHaveBeenCalledWith(`${prefix}:${itemKey}`); + expect(storagedValue).toEqual(mockedValue); + }); + it('should calls localStorage.getItem with getItemFromPattern returns undefined', () => { const safeStorage = makeSut(); const pattern = faker.random.alphaNumeric(8); diff --git a/docs/README_V1.md b/docs/README_V1.md new file mode 100644 index 0000000..bef5815 --- /dev/null +++ b/docs/README_V1.md @@ -0,0 +1,287 @@ +# Encrypt Storage +![npm](https://img.shields.io/npm/dm/encrypt-storage) [![Code Size](https://img.shields.io/github/languages/code-size/michelonsouza/encrypt-storage)](https://github.com/michelonsouza/encrypt-storage) [![Version](https://img.shields.io/github/package-json/v/michelonsouza/encrypt-storage/master)](https://github.com/michelonsouza/encrypt-storage/blob/master/package.json) [![Build Status](https://travis-ci.com/michelonsouza/encrypt-storage.svg?branch=master)](https://travis-ci.com/michelonsouza/encrypt-storage) [![Coverage Status](https://coveralls.io/repos/github/michelonsouza/encrypt-storage/badge.svg)](https://coveralls.io/github/michelonsouza/encrypt-storage) + +The `Encrypt Storage` is a `wrapper` for native `Storage` of browser. + +Using the `crypto-js` library as an encryption engine, it saves the encrypted data on the `selected storage` in the same way as the native `Storage`. + +> NOTE: Nothing on the front end is entirely secure. The library's proposal is to make it difficult for the user to see the data through the console, but as the secret key is on the front end, if the user searches hard enough, he will end up finding it. Just to make it clear that nothing is completely secure on the front end. Thank you for your attention. + +## Table of Contents + +- [Encrypt Storage](#encrypt-storage) + - [Table of Contents](#table-of-contents) + - [Features](#features) + - [Installing](#installing) + - [Examples](#examples) + - [CommonJS](#commonjs) + - [JS Import (es6)](#js-import-es6) + - [Conventions](#conventions) + - [Parameters](#parameters) + - [secretKey](#secretkey) + - [options](#options) + - [Global state management persist solutions](#global-state-management-persist-solutions) + - [redux-persist](#redux-persist) + - [vuex-persist](#vuex-persist) + - [AWS Amplify](#aws-amplify) + - [Usage](#usage) + - [setItem](#setitem) + - [getItem](#getitem) + - [removeItem](#removeitem) + - [removeItemFromPattern](#removeitemfrompattern) + - [clear](#clear) + - [key](#key) + - [length](#length) + - [encryptString](#encryptstring) + - [decryptString](#decryptstring) +- [License](#license) + +## Features + - Save encrypted data in `localStorage` and `sessionStorage` + - Recover encrypted data + - Use in the same way as native Storage + - Use with `stateManagement` persisters (`vuex-persist` and `redux-persist`) + +## Installing + +> To run this project in the development mode, you'll need to have a basic environment with NodeJs and Yarn installed. + +Using npm: + +```bash +$ npm install encrypt-storage +``` + +Or yarn: + +```bash +$ yarn add encrypt-storage +``` + +## Examples + +### CommonJS + +```typescript +const { EncryptStorage } = require('encrypt-storage'); + +const encryptStorage = EncryptStorage('secret_key', options); + +module.exports = encryptStorage +``` + +### JS Import (es6) + +```typescript +import { EncryptStorage } from 'encrypt-storage'; + +export const encryptStorage = EncryptStorage('secret_key', options); +``` +### Conventions + +Create a file in your utils folder or a folder of your choice. But I advise you to use it as a singleton, so to speak, for better use. + +``` +📦 src + ┣ 📂 utils + ┃ ┗ 📜 index.ts + ┗ 📜 index.ts +``` + +> Directory Layout + +```typescript +// const { EncryptStorage } = require('encrypt-storage'); + +export const encryptStorage = EncryptStorage('secret_key', options) +``` + +## Parameters + +### secretKey + +The `secretKey` parameter is a `string` you encrypt your data. If you use a `framework` like `ReactJS` or `VueJS` prefer to store this data in your application's `.env` file: + +```typescript +// const { EncryptStorage } = require('encrypt-storage'); + +export const encryptStorage = EncryptStorage(process.env.SECRET_KEY, options) +``` + +### options + +The options object consists of the following properties: + +|key |type |default | +|-------------------|-----------------------------------|---------------| +|prefix |`string` |`null` | +|storageType |`localStorage` or `sessionStorage` |`localStorage` | +|stateManagementUse |`boolean` |`false` | + + +*prefix*: default `null` - is optional and is the prefix of all keys used in the selected storage as shown below: + +```typescript +//... +export const encryptStorage = EncryptStorage('secret_key', { + ..., + prefix: '@prefix' +}); +``` + +in your storage: + +![storageKeyValue](./docs/resources/storageKeyValue.png) + +## Global state management persist solutions + +*stateManagementUse*: default `false` - is a `boolean` value that, when true allows the use of it with `vuex-persist` and `redux-persist`: + +### redux-persist + +```typescript +... +const persistConfig = { + key: 'root', + storage: encryptStorage, + whitelist: ['navigation'], + ... +}; +``` + +### vuex-persist + +```typescript +... +const vuexLocal = new VuexPersistence({ + storage: encryptStorage +}) +``` + +*storageType*: default `localStorage` - is the type of storage that will be used, at the moment only `localStorage` and` sessionStorage` are allowed: + +```typescript +//... +export const encryptStorage = EncryptStorage('secret_key', { + ..., + storageType: 'sessionStorage' +}); +``` + +## AWS Amplify + +In the case of `aws-amplify`, if you want to use the facility of not needing to use `JSON.parse` in the rest of the application, prefer to create an instance within the `amplify` configuration file, as follows: + +```typescript +import Amplify from 'aws-amplify'; +import { EncryptStorage } from 'encrypt-storage'; + +const encryptStorage = EncryptStorage('secret_key',{ + ..., + stateManagementUse: true, +}); + +... + +Amplify.configure({ + Auth: { + ..., + storage: encryptStorage, + }, +}); +``` +## Usage + +The usage follows the premise that encryptStorage has been "instantiated" in another file. In the example, the utils folder is used and JS imports. + +### setItem +```typescript +... +import { encryptStorage } from './utils'; + +encryptStorage.setItem('user', { name: 'John', age: 36 }); +``` +### getItem +the getItem function is slightly different from the native api because it does not need to have its data treated, when the data exists, by JSON.parse as follows: + +```typescript +... +encryptStorage.setItem('user', { name: 'John', age: 36 }); +const decryptedData = encryptStorage.getItem('user'); + +// { name: 'John', age: 36 } (is an object Javascript, not a string) +``` + +### removeItem + +Remove an item from `selectedStorage` + +```typescript +... +encryptStorage.removeItem('user'); +``` + +### removeItemFromPattern + +Remove an item from `selectedStorage` + +```typescript +... +encryptStorage.setItem('12345678:user', { id: 1234 }); +encryptStorage.setItem('12345678:item', { id: 5678 }); + +encryptStorage.removeItemFromPattern('12345678'); + +// items '12345678:user' and '12345678:item' are removed from 'selectedStorage' +``` + +### clear + +Clear all data from `selectedStorage` + +```typescript +... +encryptStorage.clear(); +``` + +### key + +Returns a key of `index` param or `null` if not exists + +```typescript +... +encryptStorage.key(0); +``` + +### length + +Returns a `quantity` of `keys` existents in `selectedStorage` + +```typescript +... +encryptStorage.length; +``` + +### encryptString +Encrypt any string and rerturn `encrypted value` +```typescript +... +import { encryptStorage } from './utils'; + +const encryptedValue = encryptStorage.encryptString('any_string'); +// 'U2FsdGVkX1/jvF6fLkGI3aALI9ssWNAPAeZ5nxeskh8=' +``` + +### decryptString +Decrypt any string (encrypted with `encryptString`) and return `decrypted value` +```typescript +... +import { encryptStorage } from './utils'; + +const decryptedValue = encryptStorage.decryptString('U2FsdGVkX1/jvF6fLkGI3aALI9ssWNAPAeZ5nxeskh8='); +// 'any_string' +``` + +# License + +[MIT License](/LICENSE) diff --git a/src/async-encrypt-storage.ts b/src/async-encrypt-storage.ts index d43dc54..989fbf5 100644 --- a/src/async-encrypt-storage.ts +++ b/src/async-encrypt-storage.ts @@ -19,7 +19,8 @@ export class AsyncEncryptStorage { public async getItem(key: string): Promise { return new Promise(resolve => { - resolve(this.encryptStorage.getItem(key)); + const storageValue = this.encryptStorage.getItem(key); + resolve(storageValue); }); } @@ -33,7 +34,8 @@ export class AsyncEncryptStorage { pattern: string, ): Promise | undefined> { return new Promise(resolve => { - resolve(this.encryptStorage.getItemFromPattern(pattern)); + const storageValues = this.encryptStorage.getItemFromPattern(pattern); + resolve(storageValues); }); } @@ -57,13 +59,15 @@ export class AsyncEncryptStorage { public async encryptString(str: string): Promise { return new Promise(resolve => { - resolve(this.encryptStorage.encryptString(str)); + const encryptedValue = this.encryptStorage.encryptString(str); + resolve(encryptedValue); }); } public async decryptString(str: string): Promise { return new Promise(resolve => { - resolve(this.encryptStorage.decryptString(str)); + const decryptedValue = this.encryptStorage.decryptString(str); + resolve(decryptedValue); }); } } diff --git a/src/encrypt-storage.ts b/src/encrypt-storage.ts index f362c3b..eb438a9 100644 --- a/src/encrypt-storage.ts +++ b/src/encrypt-storage.ts @@ -5,7 +5,6 @@ export interface EncryptStorageOptions { prefix?: string; stateManagementUse?: boolean; storageType?: 'localStorage' | 'sessionStorage'; - isAsync?: boolean; encAlgorithm?: EncAlgorithm; } @@ -196,7 +195,11 @@ export class EncryptStorage implements EncryptStorageTypes { } const value = keys.reduce((accumulator: Record, key) => { - accumulator[key] = this.getItem(key); + const formattedKey = this.prefix + ? key.replace(`${this.prefix}:`, '') + : key; + + accumulator[formattedKey] = this.getItem(formattedKey); return accumulator; }, {});