Migrate from electron-store to OS-level secure storage (getSecureStorage)

- Replace `electron-store` with OS-level encrypted storage for secure token, userId, and language management in `LocalSystem` and `keyManager`.
- Add `init-user` IPC handler to initialize user data and manage encryption keys.
- Update login process to handle encrypted storage saving with fallback for macOS issues.
- Add offline warning component to `login/page.tsx` to handle first-time sync requirements.
- Remove `electron-store` and associated dependencies from `package.json` and `package-lock.json`.
This commit is contained in:
natreex
2025-11-19 19:10:12 -05:00
parent 71d13e2b12
commit dde4683c38
11 changed files with 287 additions and 361 deletions

View File

@@ -1,33 +1,35 @@
import Store from 'electron-store';
import { getSecureStorage } from '../storage/SecureStorage.js';
/**
* Key Manager - Manages user encryption keys stored in electron-store
* Key Manager - Manages user encryption keys using OS-level secure storage
* - macOS: Keychain
* - Windows: DPAPI
* - Linux: gnome-libsecret/kwallet
*/
const store = new Store({
encryptionKey: 'eritors-scribe-secure-key'
});
/**
* Get user encryption key from secure store
* Get user encryption key from secure storage
* @param userId - User ID
* @returns User's encryption key or null if not found
* @returns User's encryption key
* @throws Error if encryption key not found
*/
export function getUserEncryptionKey(userId: string): string {
const key: string | undefined = store.get(`encryptionKey-${userId}`) as string | undefined;
if (key === undefined) {
const storage = getSecureStorage();
const key = storage.get<string>(`encryptionKey-${userId}`);
if (key === null || key === undefined) {
throw new Error(`Unknown encryptionKey`);
}
return key;
}
/**
* Set user encryption key in secure store
* Set user encryption key in secure storage (OS-encrypted)
* @param userId - User ID
* @param encryptionKey - Encryption key to store
*/
export function setUserEncryptionKey(userId: string, encryptionKey: string): void {
store.set(`encryptionKey-${userId}`, encryptionKey);
const storage = getSecureStorage();
storage.set(`encryptionKey-${userId}`, encryptionKey);
}
/**
@@ -36,7 +38,8 @@ export function setUserEncryptionKey(userId: string, encryptionKey: string): voi
* @returns True if key exists
*/
export function hasUserEncryptionKey(userId: string): boolean {
return store.has(`encryptionKey-${userId}`);
const storage = getSecureStorage();
return storage.has(`encryptionKey-${userId}`);
}
/**
@@ -44,5 +47,6 @@ export function hasUserEncryptionKey(userId: string): boolean {
* @param userId - User ID
*/
export function deleteUserEncryptionKey(userId: string): void {
store.delete(`encryptionKey-${userId}`);
const storage = getSecureStorage();
storage.delete(`encryptionKey-${userId}`);
}