Git Product home page Git Product logo

encrypt-storage's Introduction

stargazers count maintenance npm sponsors package size Code Size Version Build Status Coverage Status License Node CI CodeQL npm published jsdelivery

OBS: This is the new version of Encrypt Storage, it has breaking changes that will not be described below. For version 1.3.X documentation, access this link.

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.

HELP THIS PROJECT: Your Github star can help this project. Leave a star, it costs nothing.

โš ๏ธ IMPORTANT: 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.

Features

  • Save encrypted data in localStorage and sessionStorage
  • 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

To run this project in the development mode, you'll need to have a basic environment with NodeJs and Yarn installed.

Using npm:

$ npm install encrypt-storage

Or yarn:

$ yarn add encrypt-storage

Using CDNs:

Unpkg:

<body>
  <!-- ...after other codes -->
  <script src="https://unpkg.com/encrypt-storage@latest/dist/index.js"></script>
  <script>
    const encryptStorage = new EncryptStorage('secret-key-value');
  </script>
</body>

OBS: Unpkg doesn't have a counter badge

JS Delivery:

<body>
  <!-- ...after other codes -->
  <script src="https://cdn.jsdelivr.net/npm/encrypt-storage@latest/dist/index.js"></script>
  <script>
    const encryptStorage = new EncryptStorage('secret-key-value');
  </script>
</body>

Options

The options object is optional and consists of the following properties:

Property name Default Type required
prefix '' string false
storageType localStorage StorageType false
encAlgorithm AES EncAlgorithm false
notifyHandler undefined NotifyHandler false
stateManagementUse false boolean false
doNotEncryptValues false boolean false
doNotParseValues false boolean false

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

const { EncryptStorage } = require('encrypt-storage');

// Example of secret_key variable in an .env file
// const encryptStorage = new EncryptStorage(process.env.SECRET_KEY, options);
const encryptStorage = new EncryptStorage('secret-key-value', options);

module.exports = encryptStorage;

JS Import (ES6+)

import { EncryptStorage } from 'encrypt-storage';

// Example of secret_key variable in an .env file
// const encryptStorage = new EncryptStorage(process.env.SECRET_KEY, options);
export const encryptStorage = new EncryptStorage('secret-key-value', options);

Multiple instances

To use multiple instances, it is strictly necessary to pass the prefix to all of them. As shown below:

import { EncryptStorage } from 'encrypt-storage';

export const encryptStorage1 = new EncryptStorage('secret-key-value', {
  prefix: '@instance1',
});

export const encryptStorage2 = new EncryptStorage('secret-key-value', {
  prefix: '@instance2',
});

encryptStorage1.setItem('any-key', 'any-value');
encryptStorage2.setItem('any-key', 'any-value');

in your storage:

Key Value
@instance1:any-key U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw...
@instance2:any-key U2FsdGVkX1/w4QaIcyq5521ZXB5pqw2KEwOH+...

Options implementation

prefix

default '' - is optional and is the prefix of all keys used in the selected storage as shown below:

import { EncryptStorage } from 'encrypt-storage';

export const encryptStorage = new EncryptStorage('secret-key-value', {
  prefix: '@example',
});

storageType

default localStorage - is the type of storage that will be used, at the moment only localStorage and sessionStorage are allowed:

import { EncryptStorage } from 'encrypt-storage';

export const encryptStorage = new EncryptStorage('secret-key-value', {
  storageType: 'sessionStorage',
});

stateManagementUse

NOTE: This property is also required for completely identical use to the browser's native. Therefore, it will not have the native library behavior when parsing data to javascript objects or type casting such as 'true' being a boolean, '2' being a number, etc.

default false - is a boolean value that, when true allows the use of it with vuex-persist and redux-persist:

import { EncryptStorage } from 'encrypt-storage';

export const encryptStorage = new EncryptStorage('secret-key-value', {
  stateManagementUse: true,
});

encAlgorithm

default AES - Is the selected encryption algorithm.:

import { EncryptStorage } from 'encrypt-storage';

export const encryptStorage = new EncryptStorage('secret-key-value', {
  encAlgorithm: 'Rabbit',
});

doNotEncryptValues

default false - This option NOT encrypt values, but use those options like prefix our multiple-instances.:

import { EncryptStorage } from 'encrypt-storage';

export const encryptStorage = new EncryptStorage('secret-key-value', {
  doNotEncryptValues: true,
});

doNotParseValues

default false - This option NOT parse values, but use those options like prefix our multiple-instances.:

import { EncryptStorage } from 'encrypt-storage';

export const encryptStorage = new EncryptStorage('secret-key-value', {
  doNotParseValues: true,
});

encryptStorage.setItem('key', JSON.stringfy({ name: 'John Doe' }));

const value = JSON.parse(encryptStorage.getItem('key')); // { name: 'John Doe' }

NOTE: This option does not JSON.stringify or JSON.parse the data, making return typing useless or unnecessary. This is similar to standard browser behavior.

notifyHandler

default undefined - is a function that is called every time another EncryptStorage function is called. Good for logging API and monitoring localStorage/sessionStorage.:

import { EncryptStorage } from 'encrypt-storage';

export const encryptStorage = new EncryptStorage('secret-key-value', {
  notifyHandler: (params: NotifyHandlerParams) => console.info({ params }),
});

console:

{
  params: {
    type: 'get'
    key: 'any-key',
    value: 'any-value',
    index: 1,
  }
}

OBS: Check NotifyHandlerParams for more information.

Methods

From here, we will have the following code as the EncryptStorage instance model:

import { EncryptStorage } from 'encrypt-storage';

export const encryptStorage = new EncryptStorage('secret-key-value', {
  prefix: '@example',
});

setItem

Add key and encrypted value to selected storage.

encryptStorage.setItem('token', 'edbe38e0-748a-49c8-9f8f-b68f38dbe5a2');
encryptStorage.setItem(
  'token-not-encrypted',
  'edbe38e0-748a-49c8-9f8f-b68f38dbe5a2',
  true,
);

in your storage:

Key Value
@example:token U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw...
@example:token-not-encrypted edbe38e0-748a-49c8-9f8f-b68f38dbe5a2

setMultipleItems

Add keys and encrypted values to selected storage.

encryptStorage.setMultipleItems([
  ['token', 'edbe38e0-748a-49c8-9f8f-b68f38dbe5a2'],
  [
    'user',
    {
      id: '123456',
      name: 'John Doe',
    },
  ],
]);

in your storage:

Key Value
@example:token U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw...
@example:user U2FsdGVkX1/tT67hnb*\afcb...

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.

const value = encryptStorage.getItem<T = any>('token');
const value2 = encryptStorage.getItem<T = any>('token-not-encrypted', true);

result of getItem:

const value = 'edbe38e0-748a-49c8-9f8f-b68f38dbe5a2';
const value2 = 'edbe38e0-748a-49c8-9f8f-b68f38dbe5a2';

getMultipleItems

Returns the key value pairs decrypted or undefined by the keys passed by parameter.;

const value = encryptStorage.getMultipleItems(['token', 'user', 'any-key']);

result of getMultipleItems:

const value = {
  token: 'edbe38e0-748a-49c8-9f8f-b68f38dbe5a2',
  user: {
    id: '123456',
    name: 'John Doe',
  },
  'any-key': undefined,
};

removeItem

Remove item from selected storage.

in your storage:

Key Value
@example:token U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw...
encryptStorage.removeItem('token');

now in your storage:

Key Value

removeMultipleItems

Remove items from selected storage.

in your storage:

Key Value
@example:token U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw...
@example:user U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw...
encryptStorage.removeMultipleItems(['token', 'user']);

now in your storage:

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...
const values = encryptStorage.getItemFromPattern('fruit');

result of getItemFromPattern:

const values = {
  'fruit:apple': 'apple',
  'fruit:grape': 'grape',
};

removeItemFromPattern

Removes all items that have the pattern passed by parameter from the selected storage.

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...
encryptStorage.removeItemFromPattern('fruit');

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...
const key = encryptStorage.key(0);

result of key:

'@example:vegetable:lettuce'

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...
const length = encryptStorage.length;

result of length:

2

clear

Removes all keys and values from the selected storage.

in your storage:

Key Value
@example:vegetable:lettuce U2FsdGVkX1/tT67hnb*\afcb
@example:token U2FsdGVkX1/2KEwOH+w4QaIcyq5521ZXB5pqw...
encryptStorage.clear();

now in your storage:

Key Value

encryptString

Encrypts a string passed by parameter.

const value = encryptStorage.encryptString('John Doe');

result of encryptString:

const value = 'U2FsdGVkX1/tT67hnb*afcb';

decryptString

Decrypts a string passed by parameter.

const value = encryptStorage.decryptString('U2FsdGVkX1/tT67hnb*afcb');

result of decryptString:

const value = 'John Doe';

encryptValue

Encrypts a value passed by parameter.

const value = encryptStorage.encryptValue({
  id: '123456',
  name: 'John Doe',
});

result of encryptValue:

const value = 'U2FsdGVkX1/tT67hnb*afcb';

decryptValue

Decrypts a string passed by parameter.

// Using typescript
interface User {
  id: string;
  name: string;
}

const value = encryptStorage.decryptValue<User>('U2FsdGVkX1/tT67hnb*afcb');

result of decryptValue:

const value = {
  id: '123456',
  name: 'John Doe',
};

hash

Encrypts a string passed by parameter with SHA256 encryptation.

const value = encryptStorage.hash('John Doe');

result of hashed value:

const value =
  '52bec733f066a11182798f4defec648ea00e374a1cda73111a443b295fd8e028';

md5Hash

Encrypts a string passed by parameter with MD5 encryptation.

const value = encryptStorage.md5Hash('John Doe');

result of hashed value:

const value = '284e512750fb7d41f1cc5284a2c56a13';

NextJS

When used in NextJS, validation must be done.

example:

// utils/storage.(ts|js)
import { EncryptStorage } from 'encrypt-storage';

const encryptStorage = (): EncryptStorage | null => {
  const isInClientSide =
    typeof window !== 'undefined' && typeof window?.self !== 'undefined';

  if (isInClientSide) {
    return new EncryptStorage(
      String(process.env.NEXT_PUBLIC_STORAGE_SECRET),
      // options,
    );
  }

  return null;
};

usage:

'use client';
import { encryptStorage } from '../utils/storage.ts';

// ...rest of code
encryptStorage()?.setItem('any-key', { name: 'John Doe', age: 40 });

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.

example:

import { AsyncEncryptStorage } from 'encrypt-storage';

export const encryptStorage = new AsyncEncryptStorage('secret-key-value', options);

async function getDecryptedValue('key'): Promise<any | undefined> {
  const value = await encryptStorage.getItem('key');
}

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:

import Amplify from 'aws-amplify';
import { EncryptStorage } from 'encrypt-storage';

const encryptStorage = new EncryptStorage('secret-key-value', {
  ...,
  stateManagementUse: true,
});

...

Amplify.configure({
  Auth: {
    ...,
    storage: encryptStorage,
  },
});

State Management Persisters

This library can be used to encrypt data from state management persisters like vuex-persist, redux-persist and pinia-plugin-persist. Below are their respective implementations:

NOTE: the stateManagementUse option must be used in the EncryptStorage instance to work correctly.

vuex-persist

import VuexPersistence from 'vuex-persist';

import { encryptStorage } from 'path/to/encryptStorage';

const vuexLocal = new VuexPersistence<RootState>({
  storage: encryptStorage,
});

redux-persist

// ...
import { AsyncEncryptStorage } from 'encrypt-storage';

export const encryptStorage = new AsyncEncryptStorage('secret-key-value', options);

const persistConfig = {
  key: 'root',
  storage: encryptStorage,
  whitelist: ['navigation'],
  ...
};

pinia-plugin-persist

// ...
import { encryptStorage } from 'path/to/encryptStorage';

export const useUserStore = defineStore('storeUser', {
  state() {
    return {
      firstName: 'S',
      lastName: 'L',
      accessToken: 'xxxxxxxxxxxxx',
    };
  },
  persist: {
    enabled: true,
    strategies: [
      {
        storage: encryptStorage,
        paths: ['accessToken'],
      },
    ],
  },
});

pinia-plugin-persistedstate

import { defineStore } from 'pinia'
import { encryptStorage } from 'path/to/encryptStorage';

export const useStore = defineStore('store', {
  state: () => ({
    return: {
      first: 'John',
      last: 'Doe',
      accessToken: 'xxxxxxxxxxxxx'.
    },
  }),
  persist: {
    storage: encryptStorage,
    paths: ['accessToken'],
  },
});

License

MIT License

encrypt-storage's People

Contributors

dependabot[bot] avatar fariasmateuss avatar michelonsouza avatar pedrinslzx avatar thedoublejay avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

encrypt-storage's Issues

[question] BADENGINE

Hi,
sorry for not using the pre-defined issue template, as this is hopefully neither a bug nor an enhancement.. But I'm kinda lost and maybe someone can bring light into the dark..

Since I updated my project to the latest version of encrypt-storage I got this strange warning:

npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: '[email protected]',
npm WARN EBADENGINE   required: { npm: 'You must run yarn in this project', yarn: '1.22.x' },
npm WARN EBADENGINE   current: { node: 'v18.7.0', npm: '8.17.0' }
npm WARN EBADENGINE }

Can someone explain me what exacly this means. (yeah using yarn - haha, but with 3.7.x it worked flawlessly using npm)
Or in other words, is this critical or ignorable?

Many thanks in advance.

decryptValue get method return null for plain data

Describe the bug
When trying to read encrypted data from LS and using decryptValue, getting result as null.

Expected behavior
The data which was encrypted and stored back in LS should be retrieved back by using decrypt method

Desktop (please complete the following information):

  • OS: Linux
  • Browser - Application
  • Version 16.04

Additional context
While using decryptString, it says it is deprecated by decryptValue

encrypt-storage >=2.2.10 depends on vulnerable versions of crypto-browserify package

Describe the bug
encrypt-storage >=2.2.10 depend on vulnerable versions of crypto-browserify package as npm audit reported

To Reproduce
Steps to reproduce the behavior:

#npm audit report

elliptic  >=2.0.0
Elliptic allows BER-encoded signatures - https://github.com/advisories/GHSA-49q7-c7j4-3p7m
Elliptic's ECDSA missing check for whether leading bit of r and s is zero - https://github.com/advisories/GHSA-977x-g7h5-7qgw
Elliptic's EDDSA missing signature length check - https://github.com/advisories/GHSA-f7q4-pwc6-w24p
fix available via `npm audit fix --force`
Will install [email protected], which is a breaking change
node_modules/elliptic
  browserify-sign  >=4.0.0
  Depends on vulnerable versions of elliptic
  node_modules/browserify-sign
    crypto-browserify  >=3.11.0
    Depends on vulnerable versions of browserify-sign
    Depends on vulnerable versions of create-ecdh
    node_modules/crypto-browserify
      encrypt-storage  >=2.2.10
      Depends on vulnerable versions of crypto-browserify
      node_modules/encrypt-storage
  create-ecdh  >=4.0.0
  Depends on vulnerable versions of elliptic
  node_modules/create-ecdh

5 low severity vulnerabilities

Type 'EncryptStorage' is not assignable to type 'Storage'.

Hi,

I'm trying to use this plugin ([email protected]) with 'pinia-plugin-persist' ( [email protected])

I get the following TypeScript error:

Type 'EncryptStorage' is not assignable to type 'Storage'.
The types returned by 'getItem(...)' are incompatible between these types.

Any suggestion on how to make it work?

tsconfig.json

{
"$schema": "https://json.schemastore.org/tsconfig.json",
"extends": "@vue/tsconfig/tsconfig.web.json",
"compilerOptions": {
"target": "esnext",
(...)
"types": ["vite/client", "vitest/globals", "vue", "pinia-plugin-persist"]
},
"include": ["src//*.ts", "src//.d.ts", "src/**/.tsx", "src/**/*.vue"],
"exclude": ["node_modules", "dist", "src/client/Api.ts"],
"references": [{ "path": "./tsconfig.node.json" }]
}

encryptStorage.ts

import { EncryptStorage } from 'encrypt-storage';

export const encryptStorage = new EncryptStorage(
import.meta.env.SECRET_KEY,
{
storageType: 'localStorage',
stateManagementUse: true,
}
);

SystemStore.ts

import { defineStore } from 'pinia';
import type { encryptStorage } from '@/utils/encryptStorage';

type SystemStoreState = {

};

export default defineStore('systemStore', {
state: (): SystemStoreState => ({
persist: {
enabled: true,
strategies: [{ storage: encryptStorage }],
},
});

JSON strings don't survive `setItem`/`getItem` roundtrip

Describe the bug
When saving a string that is valid JSON with setItem, then loading it with getItem, the returned value isn't the original string, but the value obtained by parsing it as JSON.

To Reproduce
Run the following test:

const storage = new EncryptStorage('verysecret');
const value = '{}';
storage.setItem('foo', value);
expect(storage.getItem('foo')).toEqual(value);

The test fails, also with other JSON values such as 42, "a string", true, [] and null.

Expected behavior
getItem should reproduce the original string saved using setItem.

Desktop:

  • OS: Windows
  • Browser: Chrome
  • Version: 124.0.6367.119

Additional context
This behavior occurs because values with a type different from object (e.g. string) aren't JSON.stringify'd by setItem, but saved as is. getItem then tries to parse those values as JSON and returns the original string only if parsing fails. Now if the original string happens to be valid JSON, this roundtrip doesn't work.
I guess it would make sense to always JSON.stringify in setItem, even for primitive values.

API inconsistency

Hi,

I've run into an error using this library it looks like the library implements Storage interface as defined here:

https://developer.mozilla.org/en-US/docs/Web/API/Storage

but after revisiting the documentation looks like that's not true, since 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:

this is a problem because the original Storage interface doesn't do that, so any other libraries that use an Storage implementation will fail when you try to use encrypted-storage Storage implementation.

I think its not a good idea to disregard the HTML Standard in this manner, and right now this is the cause of my bug.

I'm going to fork the project and remove this problematic feature for my project. Could send a PR back.

Regards,

Invalid left-hand side in assignment (Angular)

Hey, I'm using your plugin in an angular application.
Since some weeks I have the problem, that when I try to deploy the application to the server I get the message "Invalid left-hand side in assignment"
No I was able to figure out the issue.

It's caused by two lines of your code:

window && window?.globalThis && (window?.globalThis.AsyncEncryptStorage = A)
window && window?.globalThis && (window?.globalThis.EncryptStorage = b)

And appears since this commit: 296629d and/or 85d2e7d

I can run the app again if I remove the ? behind window.
I'm not sure why you using this when you checking before if window is defined?

I hope you know what I mean and you can help me with this issue.
Thank you so much already! :-)

(If you need more information, please ask!)

Can't getItem

Describe the bug
A clear and concise description of what the bug is.

Got to create a new instance in one component:
new EncryptStorage('cid', { prefix: '@instance1', });

And tried to get the value in another component:
const token = encryptStorage.getItem<T = any>('cid');

Console message:
'encryptStorage' is not defined no-undef

Using Windows 10,
VSCode,
React

Any idea?

Name and logo of the package

The name of the repo is "Encrypt Storage" but the logo says "EncrypStorage", without the T and with no space on it.

Which one is the correct?

Not working with NextJs(SSR)

Describe the bug
ReferenceError: self is not defined

To Reproduce
Install this package in project with next js

Additional context
I guess this is due to the special behavior of the localStorage in the nextJs. I mean document or window should be defined for work with localStorage.

Invalid left-hand side in assignment (Angular)

Hey ๐Ÿ˜ƒ

the bug from #583 is still in the current version of the plugin.
People (including me) are very confused about it. Because in your comment you wrote that you promise a fix in the next version but the added tag is saying WON'T FIX.

Since the issue is closed and still people are commenting it I open this issue to continue the talk.

Hope you have a good week and greetings!

Mocking localStorage when Unit Testing Modules using Pinia/Encrypt-Storage

Hi,

We are using Vue 3 and Pinia with Encrypt-Storage.

We are implementing some unit tests in Vue and we need to mock the localStorage behind Encrypt-Storage/Pinia.

As we are using Vitest, it seems the way to is using the following package vitest-localstorage-mock.

My questions are: Do you suggest any other way to implement the unit tests of the modules using Pinia/Encrypt-Storage ? Any code example?

Thanks,

Juan

Add example for `pinia-plugin-persistedstate`

Add example for pinia-plugin-persistedstate

pinia-plugin-persistedstate is maintained and used more than pinia-plugin-persist
https://npmtrends.com/pinia-plugin-persist-vs-pinia-plugin-persistedstate

(untested.. something like?)

import { defineStore } from 'pinia'
import { encryptStorage } from 'path/to/encryptStorage';

export const useStore = defineStore('store', {
  state: () => ({
    return: {
      first: 'John',
      last: 'Doe',
      accessToken: 'xxxxxxxxxxxxx'.
    },
  }),
  persist: {
    storage: encryptStorage,
    paths: ['accessToken'],
  },
})

self is not defined

when installing the module and starting the project I get this module error

ReferenceError: self is not defined
at Object. (F:\ProyectosPago\Search\node_modules\encrypt-storage\dist\index.js:2:358)
at Module._compile (node:internal/modules/cjs/loader:1099:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:999:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Module._compile (node:internal/modules/cjs/loader:1099:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)

Error: Can't resolve 'crypto'

Describe the bug
Error occurs when building React project locally.

...

WARNING in ./node_modules/encrypt-storage/dist/index.js 2:104-121
Module not found: Error: Can't resolve 'crypto' in '/Users/foobar/workspace/ui-react/node_modules/encrypt-storage/dist'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
	- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "crypto": false }
 @ ./config/amplify.ts 1:0-49 3:27-41
 @ ./src/App.tsx 6:0-42 21:18-27
 @ ./src/index.tsx 5:0-24 14:118-121

 ...

To Reproduce
Steps to reproduce the behavior:
$ npm run build

Expected behavior
Application build with no errors.

Desktop (please complete the following information):

  • OS: macOS Big Sur 11.6
  • Browser: n/a
  • Version: "encrypt-storage": "^2.2.5"

ReferenceError: self is not defined

Describe the bug
Getting this error in next js.

To Reproduce
Steps to reproduce the behavior:
const encryptStorage = new EncryptStorage('secret-key-value', {
prefix: '@instance1',
});

encryptStorage.setItem('local', 'anyvalue');

Expected behavior
it shouldn't give any error

Desktop (please complete the following information):

  • OS: macOS
  • Browser [ chrome, safari, brave, firefox]

Screenshots
If applicable, add screenshots to help explain your problem.
Screen Shot 2023-01-16 at 21 33 58 PM

Additional context

error - ReferenceError: self is not defined
at Object.<anonymous> (/<path>/node_modules/encrypt-storage/dist/index.js:2:236)

    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1155:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)

  at Object.encrypt-storage (/<path>/.next/server/pages/login.js:4065:18)
      at __webpack_require__ (/<path>/.next/server/webpack-runtime.js:33:42)
      at eval (webpack-internal:///./src/pages/login.tsx:19:73)
      at Function.__webpack_require__.a (/<path>/.next/server/webpack-runtime.js:97:13)
      at eval (webpack-internal:///./src/pages/login.tsx:1:21)
      at Object../src/pages/login.tsx (/<path>/.next/server/pages/login.js:3276:1)
      at __webpack_require__ (/<path>/.next/server/webpack-runtime.js:33:42)
      at __webpack_exec__ (/<path>/.next/server/pages/login.js:4669:39)
      at /<path>/.next/server/pages/login.js:4670:28 {
    page: '/login'
}```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.