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!
vault.key1 = "value1";
vault.key2 = "value2";
const value1 = await vault.key1;
const value2 = await vault.key2;
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';
const authStorage = new SecuredVault("auth-storage", {
password: "SADF@#$W$ERWESD",
salt: "SDF@#$%SERWESD",
});
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 };
});
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:
- Use dynamic credentials for the secured storage it takes care of managing the complexity of the credentials.
- 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.
- Generate and store encryption credentials using the Web Crypto API to ensure they are not accessible via JavaScript.
- Fetch encrypted credentials from the server instead of raw passwords and salts. Decrypt credentials locally using a pre-shared or derived key.
- Use CSP headers to mitigate XSS attacks
- Run your application in a secure context (HTTPS)
- Either use periodically rotate the encryption credentials or generate a unique ones for each storage key.
await authStorage.setItem("token", authToken)
const authToken = await authStorage.token;
Setting Values
Store data using the setItem
method, indexer syntax, or dot notation:
vault.setItem('yourKey', { any: 'data' });
vault['yourKey'] = { any: 'data' };
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.
const data = await vault.getItem('yourKey');
const data = await vault['yourKey'];
const data = await vault.yourKey;
Removing Values
Remove data using the removeItem
method:
vault.removeItem('yourKey');
delete vault['yourKey'];
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.
vault.setItem('yourKey', { any: 'data' }, {
roles: ['editor', 'moderator'],
});
const meta = await vault.getItemMeta('yourKey');
console.log(`yourKey is marked for '${meta.roles}' roles! `);
if (user.roles.some(role => meta.roles.includes(role))) {
}
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);
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();
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
Advanced Features - Encryption
Other Advanced Features
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.