Skip to content

Vault is a sophisticated browser-based storage micro library that leverages the power of IndexedDB, offering significant improvements (Such as larger async secured storages) over traditional LocalStorage.

License

Notifications You must be signed in to change notification settings

maniartech/vault

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vault Storage

Vault Storage is a sophisticated browser-based storage library that leverages the power of IndexedDB, offering significant improvements over traditional LocalStorage. As a high-performance, asynchronous solution for client-side storage, it provides an intuitive and easy-to-use API similar to local and session storage, increasing the capacity of the storage, and adding support for structured data, and support for multiple stores. It also provides a secure storage for sensitive data.

Features

  • Similar API: Easy to use, similar to LocalStorage.
  • Lightweight: No dependencies, micro footprint
    • Less than a KB (minified and gzipped), unsecured vault
    • Around a KB (minified and gzipped), secured vault
  • Multiple Stores Support: Supports multiple stores with single api.
  • Store Additional Meta Data: Store additional meta data along with the item value.
  • Encrypted Vault: Provides a secure storage for sensitive data.
  • Backup and Restore: Export and import the vault storage data.
  • Asynchronous: Non-blocking, asynchronous API.
  • Structured Data: Supports structured data, including objects and arrays.

Installation

Install vault-storage using npm:

npm install vault-storage --save

Or using yarn:

yarn add vault-storage

Usage

First, import the vault from vault-storage. The vault is a default instance of the Vault storage class and hence does not need any special initialization or setup!!! The vault provides a ready to use instance similar to localStorage and sessionStorage. You can start using it right away without any setup.

import vault from 'vault-storage';

Initializing and Setup

Just start using it!

// Set the values.
vault.key1 = "value1";
vault.key2 = "value2";

// Get the values. Remember to use await! As it's asynchronous.
const value1 = await vault.key1; // "value1"
const value2 = await vault.key2; // "value2"

Custom Storage

You can also create a custom storage. This is useful when you want to use multiple storages for different purposes. All the custom storage also share the same API as the default vault storage and other built-in storages like localStorage and sessionStorage.

import Vault from 'vault-storage/vault';


const appStorage = new Vault("app-storage")
appStorage.setItem("key", "value")
console.log("key", await appStorage.getItem("key"))

const userStorage = new Vault("user-storage")
userStorage.setItem("key", "value")

Secured Storage

Secured storages are useful when you want to store sensitive data. It shares the same API but it encrypts the data before storing it in the storage. It uses browser's native crypto API to encrypt the data. The secured storage can be created using a fixed credentials or dynamic credentials (credentials that are generated based on the key).

import SecuredVault from 'vault-storage/secured-vault';

// Secured storage using fixed credentials (password and salt).
// Remember, this method is not secure as the credentials are hardcoded in the code.
// For production, you must use dynamic credentials.
const authStorage = new SecuredVault("auth-storage", {
  password: "SADF@#$W$ERWESD",
  salt: "SDF@#$%SERWESD",
});

// -----

// Secured storage using dynamic credentials.
const authStorage = new SecuredVault("auth-storage", (key) => {
  const password = key === "token" ? "ASF@#$%QER()SDF" : "SXDFW#$%@#SDF";
  const salt = key.startsWith("key1") ? "xxx@xxxxxxxxxx" : "yyy@yyyyyyyyyy";
  return { password, salt };
});

// -----

// Secured storage using promise based dynamic credentials.
const authStorage = new SecuredVault("auth-storage", async (storageKey) => {
  return new Promise(async (resolve) => {
    const encryptedKey = await encryptKey(storageKey)
    const encryptedResponse = await fetchOrGenerateCredentialsFor(encryptedKey)
    const { password, salt } = await decryptResponse(encryptedResponse)
    resolve({ password, salt })
  });
});

Once the secured vault is setup, usage is easy and similar to the regular vault storage. To ensure that the data is stored securely, you must follow the best practices for storing the credentials. Such as:

  1. Use dynamic credentials for the secured storage it takes care of managing the complexity of the credentials.
  2. Use asymmetric encryption for key transmission. Encrypt sensitive keys using a public key before sending them to the server. Decrypt the keys locally using a private key.
  3. Generate and store encryption credentials using the Web Crypto API to ensure they are not accessible via JavaScript.
  4. Fetch encrypted credentials from the server instead of raw passwords and salts. Decrypt credentials locally using a pre-shared or derived key.
  5. Use CSP headers to mitigate XSS attacks
  6. Run your application in a secure context (HTTPS)
  7. Either use periodically rotate the encryption credentials or generate a unique ones for each storage key.
// This is how you can use the enrypted storage, authStorage, created above.

// Set the values. It stores the encrypted Uint8Array in the storage
// against the key. If you want to immediately use the value, then
// you must use await while setting the value.
await authStorage.setItem("token", authToken)

// Somewhere else in the code, you can get the value using the following code.
const authToken = await authStorage.token; // Decrypts the token from the authStorage
                                           // and returns the plain token.

Setting Values

Store data using the setItem method, indexer syntax, or dot notation:

 // For set operation you can ignore await unless you want to wait for the
 // operation to complete or you want to catch any errors.
vault.setItem('yourKey', { any: 'data' });

// Indexer syntax.
vault['yourKey'] = { any: 'data' };

// Dot notation.
vault.yourKey = { any: 'data' };

Getting Values

Retrieve data using the getItem method, indexer syntax, or dot notation. For get operations you must use await as it's asynchronous.

// Get the value using the getItem method.
const data = await vault.getItem('yourKey');

// Indexer syntax.
const data = await vault['yourKey'];

// Dot notation.
const data = await vault.yourKey;

Removing Values

Remove data using the removeItem method:

// Remove the value using the remove method.
vault.removeItem('yourKey');

// Indexer syntax.
delete vault['yourKey'];

// Dot notation.
delete vault.yourKey;

Clearing All Data

Clear all data from the store:

await vault.clear();

Getting Store Length

Get the count of entries in the store:

const count = await vault.length();
console.log(count);

Working with Item Meta Data

You can also store meta data along with the item value. The meta data is useful when you want to store some additional information about the item. The meta data is stored along with the item value and can be retrieved using the getItemMeta method.

// Set the additional meta data along with the item value.
vault.setItem('yourKey', { any: 'data' }, {
  roles: ['editor', 'moderator'],
});

// Get the meta data for the specified item.
const meta = await vault.getItemMeta('yourKey');
console.log(`yourKey is marked for '${meta.roles}' roles! `);

if (user.roles.some(role => meta.roles.includes(role))) {
  // User has access to the specified item in the vault.
}

Backup and Restore Vault Storage

With version 1.3 and above, you can export and import the vault storage data. Please note that while exporting the secured storage data, the data is exported in non-encrypted form. You must be careful while exporting the data and ensure that the data is exported in a secure manner.

We are still considering the best way to export the secured storage data in an encrypted form. If you have any suggestions, please let us know.

import { importData, exportData } from 'vault-storage/backup';

const data = await exportData(vault);

// You can now save the data to a file or send it to the server.
// For example, you can save the data to a file using the following code.
const blob = new Blob([JSON.stringify(data)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url
a.download = 'vault-data.json';
a.click();

// To import the data back to the vault, you can use the following code.
const importedData = await importData(data);

API Reference

Vault Class

The Vault class is the cornerstone of our storage capabilities, providing a functionality akin to localStorage and sessionStorage. It empowers you to establish custom storage instances, offering a intuitive and user-friendly API for data storage and retrieval. Here's a rundown of the methods available in the Vault class:

import Vault from 'vault-storage/vault';
  • setItem(key: string, value: any, meta: any): Store data in the storage.
  • getItem(key: string): Retrieve data from the storage.
  • removeItem(key: string): Remove data from the storage.
  • clear(): Clear all data from the storage.
  • length(): Get the count of entries in the storage.

vault Default Instance

The vault is a default instance of the Vault class, providing a ready-to-use storage solution without any setup or initialization.

import vault from 'vault-storage';

SecuredVault Class

The SecuredVault class is a provides a secure storage for sensitive data. It encrypts the data before storing it in the storage. It uses browser's native crypto API to encrypt the data. The secured storage can be created using a fixed credentials or dynamic credentials (credentials that are generated based on the key). For more information, refer to the usage section above.

Import and Export Functions

Additionally, the vault-storage library offers two functions for exporting and importing vault storage data:

import { importData, exportData } from 'vault-storage/backup';
  • exportData(vault: Vault): Export the vault storage data.
  • importData(data: any): Import the vault storage data.

Comparing Vault storage with LocalStorage

Feature Vault LocalStorage
API Complexity Simple, intuitive API Simple, intuitive API
Capacity Large (up to browser limit, often no less than 250MB) Limited (5MB typical)
Multiple Stores Supports multiple stores Single store
Meta Data Supports storing meta data along with the item value No support for meta data
Encrypted Storage Supports built-in encrypted storage No built-in encryption support
Data Types Supports structured data, including objects and arrays Only stores strings
Built-in Data Import/Export Supports backup and restore of the vault storage No built-in support for data import/export
Performance Asynchronous, non-blocking Synchronous, can block UI

The Roadmap

Since the vault is baesd on IndexDB database as storage provider, it is possible to make it more powerful and useful. Here are some planned features and their implementation status.

Core Features

  • Extensible Vault class that has following qualities (v1.0.*)
    • Provides a simple interface similar to local and session storages
    • Supports indexers and dot notation for intuitive and ergonomic access
    • Store large amount of data
    • Perorm transactional in non-blocking asynchronous manner
  • Global default vault instance for ease of use (v1.0.*)
  • Support custom databases (v1.0.*)

Advanced Features - Encryption

  • Support for secured vault storage (v1.1.*)
  • Support for dynamic password and salt for secured vault storage (v1.0.*)

Other Advanced Features

  • Support for storing and retriving meta data along with item values. (v1.2.*)
  • Support for vault data backup and restore (v1.3.*)
  • Automatic expiration of values through expires meta data. (Future)

Contributing

Contributions to vault-storage are welcome. Please ensure that your code adheres to the existing style and includes tests covering new features or bug fixes.

License

vault-storage is MIT licensed.

About

Vault is a sophisticated browser-based storage micro library that leverages the power of IndexedDB, offering significant improvements (Such as larger async secured storages) over traditional LocalStorage.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published