Files
obsidian-mcp-server/tests/encryption-utils.test.ts
Bill cb21681dd0 feat: add API key encryption utilities using Electron safeStorage
Implement encryption utilities for securely storing API keys:
- encryptApiKey(): encrypts keys using Electron safeStorage with base64 encoding
- decryptApiKey(): decrypts stored keys
- isEncryptionAvailable(): checks platform support

Encryption falls back to plaintext on platforms without keyring support.
Includes comprehensive test coverage with Electron mock.
2025-10-25 22:14:29 -04:00

74 lines
2.0 KiB
TypeScript

import { encryptApiKey, decryptApiKey } from '../src/utils/encryption-utils';
// Mock electron module
jest.mock('electron', () => ({
safeStorage: {
isEncryptionAvailable: jest.fn(() => true),
encryptString: jest.fn((data: string) => Buffer.from(`encrypted:${data}`)),
decryptString: jest.fn((buffer: Buffer) => {
const str = buffer.toString();
return str.replace('encrypted:', '');
})
}
}));
describe('Encryption Utils', () => {
describe('encryptApiKey', () => {
it('should encrypt API key when encryption is available', () => {
const apiKey = 'test-api-key-12345';
const encrypted = encryptApiKey(apiKey);
expect(encrypted).toMatch(/^encrypted:/);
expect(encrypted).not.toContain('test-api-key-12345');
});
it('should return plaintext when encryption is not available', () => {
const { safeStorage } = require('electron');
safeStorage.isEncryptionAvailable.mockReturnValueOnce(false);
const apiKey = 'test-api-key-12345';
const result = encryptApiKey(apiKey);
expect(result).toBe(apiKey);
});
it('should handle empty string', () => {
const result = encryptApiKey('');
expect(result).toBe('');
});
});
describe('decryptApiKey', () => {
it('should decrypt encrypted API key', () => {
const apiKey = 'test-api-key-12345';
const encrypted = encryptApiKey(apiKey);
const decrypted = decryptApiKey(encrypted);
expect(decrypted).toBe(apiKey);
});
it('should return plaintext if not encrypted format', () => {
const plaintext = 'plain-api-key';
const result = decryptApiKey(plaintext);
expect(result).toBe(plaintext);
});
it('should handle empty string', () => {
const result = decryptApiKey('');
expect(result).toBe('');
});
});
describe('round-trip encryption', () => {
it('should successfully encrypt and decrypt', () => {
const original = 'my-secret-api-key-abc123';
const encrypted = encryptApiKey(original);
const decrypted = decryptApiKey(encrypted);
expect(decrypted).toBe(original);
expect(encrypted).not.toBe(original);
});
});
});