json-secure-store
v1.0.11
Published
Typed JSON storage wrapper for localStorage/sessionStorage with optional encryption.
Maintainers
Readme
json-secure-store
A lightweight, TypeScript-first utility for storing JSON objects in localStorage or sessionStorage, with optional encryption, expiration, type-safe access, and change listeners. Framework-agnostic and blazing fast.
✨ Features
- Local/session storage support
- Optional encryption (Web Crypto API, providing modern, dependency-free AES-GCM encryption with PBKDF2 key derivation.)
- Typed access with interfaces or models
- Expiration support (TTL)
- Change listeners
- Framework agnostic (works in Angular, React, Vue, plain JS, etc.)
Usage
Basic Store / Get / Remove
import { JsonStore } from 'json-secure-store';
const store = new JsonStore();
// Store an object
await store.setItem('user', { name: 'Alice', role: 'admin' });
// Retrieve the object with type safety
const user = await store.getItem<{ name: string; role: string }>('user');
console.log(user?.name); // "Alice"
// Remove the item
store.removeItem('user');With Encryption
import { JsonStore } from 'json-secure-store';
// Example: Using encryption (AES-GCM via Web Crypto API)
const store = new JsonStore({ encrypt: true, encryptionKey: 'your-secret-key' });
await store.setItem('secureKey', { data: 'secret' });
const decrypted = await store.getItem<{ data: string }>('secureKey');
console.log(decrypted?.data); // "secret"With Expiration
import { JsonStore } from 'json-secure-store';
const store = new JsonStore();
// Store an item that expires in 60 seconds
await store.setItem('session', { userId: 123 }, { ttl: 60000 });
// Retrieve the item before it expires
const session = await store.getItem<{ userId: number }>('session');
console.log(session?.userId); // 123Switching Between localStorage and sessionStorage:
import { JsonStore, StorageType } from 'json-secure-store';
const localStore = new JsonStore({ storageType: StorageType.Local });
const sessionStore = new JsonStore({ storageType: StorageType.Session });
// Store an item in localStorage
await localStore.setItem('user', { name: 'Alice' });
// Store an item in sessionStorage
await sessionStore.setItem('session', { sessionId: '12345' });Using Cache
import { JsonStore } from 'json-secure-store';
const store = new JsonStore({ cache: true });
// Store an item with caching enabled
await store.setItem('user', { name: 'Alice' });
// Retrieve from cache if available
const cachedUser = await store.getItem('user');
console.log(cachedUser?.name); // "Alice"Listen for Changes
import { JsonStore } from 'json-secure-store';
const store = new JsonStore();
store.onChange((key, newValue) => {
console.log(`Changed key: ${key}, new value:`, newValue);
});
// Trigger a change
await store.setItem('user', { name: 'Alice' });Angular Integration Example
1. Install the package:
npm install json-secure-store2. Create a service to encapsulate storage operations:
import { Injectable } from '@angular/core';
import { JsonStore } from 'json-secure-store';
@Injectable({
providedIn: 'root',
})
export class SecureStorageService {
private store: JsonStore;
constructor() {
this.store = new JsonStore({ encrypt: true, encryptionKey: 'your-encryption-key' });
}
async setItem<T>(key: string, value: T, ttl?: number): Promise<void> {
await this.store.setItem(key, value, ttl ? { ttl } : undefined);
}
async getItem<T>(key: string): Promise<T | null> {
return await this.store.getItem<T>(key);
}
removeItem(key: string): void {
this.store.removeItem(key);
}
}3. Use the service in your components:
import { Component, OnInit } from '@angular/core';
import { SecureStorageService } from './secure-storage.service';
@Component({
selector: 'app-example',
template: `<p>{{ userData?.name }}</p>`,
})
export class ExampleComponent implements OnInit {
userData: { name: string; role: string } | null = null;
constructor(private secureStorageService: SecureStorageService) {}
async ngOnInit(): Promise<void> {
// Store data
await this.secureStorageService.setItem('user', { name: 'Alice', role: 'admin' });
// Retrieve data
this.userData = await this.secureStorageService.getItem<{ name: string; role: string }>('user');
}
}API
Constructor Options
export interface StorageOptions {
storageType?: StorageType;
encrypt?: boolean;
encryptionKey?: string;
cache?: boolean;
namespace?: string;
defaultTTL?: number;
}Methods
store.setItem<T>(key: string, value: T, options?: { ttl?: number }): Promise<void>;
store.getItem<T>(key: string): Promise<T | null>;
store.removeItem(key: string): void;
store.clear(): void;
store.onChange(callback: (key: string, value: any) => void): void;
store.raw(): Storage;Encryption
- Utilizes AES-GCM encryption via the Web Crypto API.
- Requires encrypt: true and encryptionKey for encryption.
Expiration (TTL)
- Use
defaultTTL(in milliseconds) to auto-expire items. - Items with expired TTL are removed on retrieval.
Type Guards (Optional)
function isUser(val: any): val is User {
return val && typeof val.name === 'string';
}
const user = await store.getItem('user');
if (isUser(user)) {
console.log(user.name);
}Testing
npm run testUtilizes Vitest for fast, browser-like testing.
