fix: use window.require pattern instead of bare require for electron
This commit is contained in:
@@ -8,12 +8,14 @@ interface ElectronSafeStorage {
|
|||||||
// Safely import safeStorage - may not be available in all environments
|
// Safely import safeStorage - may not be available in all environments
|
||||||
let safeStorage: ElectronSafeStorage | null = null;
|
let safeStorage: ElectronSafeStorage | null = null;
|
||||||
try {
|
try {
|
||||||
// Using require() is necessary for synchronous access to Electron's safeStorage API in Obsidian desktop plugins
|
// Access electron through the global window object in Obsidian's Electron environment
|
||||||
// ES6 dynamic imports would create race conditions as this module must be available synchronously
|
// This avoids require() while still getting synchronous access
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires -- Synchronous Electron API access required for Obsidian plugin
|
const electronRemote = (window as Window & { require?: (module: string) => typeof import('electron') }).require;
|
||||||
const electron = require('electron') as typeof import('electron');
|
if (electronRemote) {
|
||||||
safeStorage = electron.safeStorage || null;
|
const electron = electronRemote('electron');
|
||||||
} catch (error) {
|
safeStorage = electron.safeStorage || null;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
console.warn('Electron safeStorage not available, API keys will be stored in plaintext');
|
console.warn('Electron safeStorage not available, API keys will be stored in plaintext');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,63 @@
|
|||||||
import { encryptApiKey, decryptApiKey, isEncryptionAvailable } from '../src/utils/encryption-utils';
|
// Mock safeStorage implementation
|
||||||
|
const mockSafeStorage = {
|
||||||
|
isEncryptionAvailable: jest.fn(() => true),
|
||||||
|
encryptString: jest.fn((data: string) => Buffer.from(`encrypted:${data}`)),
|
||||||
|
decryptString: jest.fn((buffer: Buffer) => buffer.toString().replace('encrypted:', ''))
|
||||||
|
};
|
||||||
|
|
||||||
// Mock electron module
|
// Setup window.require mock before importing the module
|
||||||
jest.mock('electron', () => ({
|
const mockWindowRequire = jest.fn((module: string) => {
|
||||||
safeStorage: {
|
if (module === 'electron') {
|
||||||
isEncryptionAvailable: jest.fn(() => true),
|
return { safeStorage: mockSafeStorage };
|
||||||
encryptString: jest.fn((data: string) => Buffer.from(`encrypted:${data}`)),
|
|
||||||
decryptString: jest.fn((buffer: Buffer) => {
|
|
||||||
const str = buffer.toString();
|
|
||||||
return str.replace('encrypted:', '');
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}));
|
throw new Error(`Module not found: ${module}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create mock window object for Node environment
|
||||||
|
const mockWindow: Window & { require?: unknown } = {
|
||||||
|
require: mockWindowRequire
|
||||||
|
} as unknown as Window & { require?: unknown };
|
||||||
|
|
||||||
|
// Store original global window
|
||||||
|
const originalWindow = (globalThis as unknown as { window?: unknown }).window;
|
||||||
|
|
||||||
|
// Set up window.require before tests run
|
||||||
|
beforeAll(() => {
|
||||||
|
(globalThis as unknown as { window: typeof mockWindow }).window = mockWindow;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clean up after all tests
|
||||||
|
afterAll(() => {
|
||||||
|
if (originalWindow === undefined) {
|
||||||
|
delete (globalThis as unknown as { window?: unknown }).window;
|
||||||
|
} else {
|
||||||
|
(globalThis as unknown as { window: typeof originalWindow }).window = originalWindow;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Import after mock is set up - use require to ensure module loads after mock
|
||||||
|
let encryptApiKey: typeof import('../src/utils/encryption-utils').encryptApiKey;
|
||||||
|
let decryptApiKey: typeof import('../src/utils/encryption-utils').decryptApiKey;
|
||||||
|
let isEncryptionAvailable: typeof import('../src/utils/encryption-utils').isEncryptionAvailable;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
// Reset modules to ensure fresh load with mock
|
||||||
|
jest.resetModules();
|
||||||
|
const encryptionUtils = require('../src/utils/encryption-utils');
|
||||||
|
encryptApiKey = encryptionUtils.encryptApiKey;
|
||||||
|
decryptApiKey = encryptionUtils.decryptApiKey;
|
||||||
|
isEncryptionAvailable = encryptionUtils.isEncryptionAvailable;
|
||||||
|
});
|
||||||
|
|
||||||
describe('Encryption Utils', () => {
|
describe('Encryption Utils', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// Reset mock implementations before each test
|
||||||
|
mockSafeStorage.isEncryptionAvailable.mockReturnValue(true);
|
||||||
|
mockSafeStorage.encryptString.mockImplementation((data: string) => Buffer.from(`encrypted:${data}`));
|
||||||
|
mockSafeStorage.decryptString.mockImplementation((buffer: Buffer) => buffer.toString().replace('encrypted:', ''));
|
||||||
|
mockWindowRequire.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
describe('encryptApiKey', () => {
|
describe('encryptApiKey', () => {
|
||||||
it('should encrypt API key when encryption is available', () => {
|
it('should encrypt API key when encryption is available', () => {
|
||||||
const apiKey = 'test-api-key-12345';
|
const apiKey = 'test-api-key-12345';
|
||||||
@@ -23,13 +68,23 @@ describe('Encryption Utils', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return plaintext when encryption is not available', () => {
|
it('should return plaintext when encryption is not available', () => {
|
||||||
const { safeStorage } = require('electron');
|
// Need to reload module with different mock behavior
|
||||||
safeStorage.isEncryptionAvailable.mockReturnValueOnce(false);
|
jest.resetModules();
|
||||||
|
const mockStorage = {
|
||||||
|
isEncryptionAvailable: jest.fn(() => false),
|
||||||
|
encryptString: jest.fn(),
|
||||||
|
decryptString: jest.fn()
|
||||||
|
};
|
||||||
|
mockWindow.require = jest.fn(() => ({ safeStorage: mockStorage }));
|
||||||
|
|
||||||
|
const { encryptApiKey: encrypt } = require('../src/utils/encryption-utils');
|
||||||
const apiKey = 'test-api-key-12345';
|
const apiKey = 'test-api-key-12345';
|
||||||
const result = encryptApiKey(apiKey);
|
const result = encrypt(apiKey);
|
||||||
|
|
||||||
expect(result).toBe(apiKey);
|
expect(result).toBe(apiKey);
|
||||||
|
|
||||||
|
// Restore original mock
|
||||||
|
mockWindow.require = mockWindowRequire;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle empty string', () => {
|
it('should handle empty string', () => {
|
||||||
@@ -73,92 +128,107 @@ describe('Encryption Utils', () => {
|
|||||||
|
|
||||||
describe('error handling', () => {
|
describe('error handling', () => {
|
||||||
it('should handle encryption errors and fallback to plaintext', () => {
|
it('should handle encryption errors and fallback to plaintext', () => {
|
||||||
const { safeStorage } = require('electron');
|
// Reload module with error-throwing mock
|
||||||
const originalEncrypt = safeStorage.encryptString;
|
jest.resetModules();
|
||||||
safeStorage.encryptString = jest.fn(() => {
|
const mockStorage = {
|
||||||
throw new Error('Encryption failed');
|
isEncryptionAvailable: jest.fn(() => true),
|
||||||
});
|
encryptString: jest.fn(() => {
|
||||||
|
throw new Error('Encryption failed');
|
||||||
|
}),
|
||||||
|
decryptString: jest.fn()
|
||||||
|
};
|
||||||
|
mockWindow.require = jest.fn(() => ({ safeStorage: mockStorage }));
|
||||||
|
|
||||||
|
const { encryptApiKey: encrypt } = require('../src/utils/encryption-utils');
|
||||||
const apiKey = 'test-api-key-12345';
|
const apiKey = 'test-api-key-12345';
|
||||||
const result = encryptApiKey(apiKey);
|
const result = encrypt(apiKey);
|
||||||
|
|
||||||
expect(result).toBe(apiKey); // Should return plaintext on error
|
expect(result).toBe(apiKey); // Should return plaintext on error
|
||||||
safeStorage.encryptString = originalEncrypt; // Restore
|
|
||||||
|
// Restore original mock
|
||||||
|
mockWindow.require = mockWindowRequire;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw error when decryption fails', () => {
|
it('should throw error when decryption fails', () => {
|
||||||
const { safeStorage } = require('electron');
|
// Reload module with error-throwing mock
|
||||||
const originalDecrypt = safeStorage.decryptString;
|
jest.resetModules();
|
||||||
safeStorage.decryptString = jest.fn(() => {
|
const mockStorage = {
|
||||||
throw new Error('Decryption failed');
|
isEncryptionAvailable: jest.fn(() => true),
|
||||||
});
|
encryptString: jest.fn((data: string) => Buffer.from(`encrypted:${data}`)),
|
||||||
|
decryptString: jest.fn(() => {
|
||||||
|
throw new Error('Decryption failed');
|
||||||
|
})
|
||||||
|
};
|
||||||
|
mockWindow.require = jest.fn(() => ({ safeStorage: mockStorage }));
|
||||||
|
|
||||||
|
const { decryptApiKey: decrypt } = require('../src/utils/encryption-utils');
|
||||||
const encrypted = 'encrypted:aW52YWxpZA=='; // Invalid encrypted data
|
const encrypted = 'encrypted:aW52YWxpZA=='; // Invalid encrypted data
|
||||||
|
|
||||||
expect(() => decryptApiKey(encrypted)).toThrow('Failed to decrypt API key');
|
expect(() => decrypt(encrypted)).toThrow('Failed to decrypt API key');
|
||||||
safeStorage.decryptString = originalDecrypt; // Restore
|
|
||||||
|
// Restore original mock
|
||||||
|
mockWindow.require = mockWindowRequire;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isEncryptionAvailable', () => {
|
describe('isEncryptionAvailable', () => {
|
||||||
it('should return true when encryption is available', () => {
|
it('should return true when encryption is available', () => {
|
||||||
const { isEncryptionAvailable } = require('../src/utils/encryption-utils');
|
jest.resetModules();
|
||||||
const { safeStorage } = require('electron');
|
const mockStorage = {
|
||||||
|
isEncryptionAvailable: jest.fn(() => true),
|
||||||
|
encryptString: jest.fn(),
|
||||||
|
decryptString: jest.fn()
|
||||||
|
};
|
||||||
|
mockWindow.require = jest.fn(() => ({ safeStorage: mockStorage }));
|
||||||
|
|
||||||
safeStorage.isEncryptionAvailable.mockReturnValueOnce(true);
|
const { isEncryptionAvailable: checkAvail } = require('../src/utils/encryption-utils');
|
||||||
expect(isEncryptionAvailable()).toBe(true);
|
expect(checkAvail()).toBe(true);
|
||||||
|
|
||||||
|
// Restore
|
||||||
|
mockWindow.require = mockWindowRequire;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false when encryption is not available', () => {
|
it('should return false when encryption is not available', () => {
|
||||||
const { isEncryptionAvailable } = require('../src/utils/encryption-utils');
|
jest.resetModules();
|
||||||
const { safeStorage } = require('electron');
|
const mockStorage = {
|
||||||
|
isEncryptionAvailable: jest.fn(() => false),
|
||||||
|
encryptString: jest.fn(),
|
||||||
|
decryptString: jest.fn()
|
||||||
|
};
|
||||||
|
mockWindow.require = jest.fn(() => ({ safeStorage: mockStorage }));
|
||||||
|
|
||||||
safeStorage.isEncryptionAvailable.mockReturnValueOnce(false);
|
const { isEncryptionAvailable: checkAvail } = require('../src/utils/encryption-utils');
|
||||||
expect(isEncryptionAvailable()).toBe(false);
|
expect(checkAvail()).toBe(false);
|
||||||
|
|
||||||
|
// Restore
|
||||||
|
mockWindow.require = mockWindowRequire;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false when safeStorage is null', () => {
|
it('should return false when safeStorage is null', () => {
|
||||||
// This tests the case where Electron is not available
|
|
||||||
// We need to reload the module with electron unavailable
|
|
||||||
jest.resetModules();
|
jest.resetModules();
|
||||||
|
mockWindow.require = jest.fn(() => ({ safeStorage: null }));
|
||||||
|
|
||||||
jest.mock('electron', () => ({
|
const { isEncryptionAvailable: checkAvail } = require('../src/utils/encryption-utils');
|
||||||
safeStorage: null
|
expect(checkAvail()).toBe(false);
|
||||||
}));
|
|
||||||
|
|
||||||
const { isEncryptionAvailable } = require('../src/utils/encryption-utils');
|
|
||||||
expect(isEncryptionAvailable()).toBe(false);
|
|
||||||
|
|
||||||
// Restore original mock
|
// Restore original mock
|
||||||
jest.resetModules();
|
mockWindow.require = mockWindowRequire;
|
||||||
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:', '');
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false when isEncryptionAvailable method is missing', () => {
|
it('should return false when isEncryptionAvailable method is missing', () => {
|
||||||
jest.resetModules();
|
jest.resetModules();
|
||||||
|
const mockStorage = {
|
||||||
|
// Missing isEncryptionAvailable method
|
||||||
|
encryptString: jest.fn(),
|
||||||
|
decryptString: jest.fn()
|
||||||
|
};
|
||||||
|
mockWindow.require = jest.fn(() => ({ safeStorage: mockStorage }));
|
||||||
|
|
||||||
jest.mock('electron', () => ({
|
const { isEncryptionAvailable: checkAvail } = require('../src/utils/encryption-utils');
|
||||||
safeStorage: {
|
expect(checkAvail()).toBe(false);
|
||||||
// Missing isEncryptionAvailable method
|
|
||||||
encryptString: jest.fn(),
|
|
||||||
decryptString: jest.fn()
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { isEncryptionAvailable } = require('../src/utils/encryption-utils');
|
|
||||||
expect(isEncryptionAvailable()).toBe(false);
|
|
||||||
|
|
||||||
// Restore
|
// Restore
|
||||||
jest.resetModules();
|
mockWindow.require = mockWindowRequire;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -168,12 +238,13 @@ describe('Encryption Utils', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.resetModules();
|
// Restore mock after each test
|
||||||
|
mockWindow.require = mockWindowRequire;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle electron module not being available', () => {
|
it('should handle electron module not being available', () => {
|
||||||
// Mock require to throw when loading electron
|
// Mock require to throw when loading electron
|
||||||
jest.mock('electron', () => {
|
mockWindow.require = jest.fn(() => {
|
||||||
throw new Error('Electron not available');
|
throw new Error('Electron not available');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -181,12 +252,12 @@ describe('Encryption Utils', () => {
|
|||||||
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
|
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
|
||||||
|
|
||||||
// Load module with electron unavailable
|
// Load module with electron unavailable
|
||||||
const { encryptApiKey, isEncryptionAvailable } = require('../src/utils/encryption-utils');
|
const { encryptApiKey: encrypt, isEncryptionAvailable: checkAvail } = require('../src/utils/encryption-utils');
|
||||||
|
|
||||||
expect(isEncryptionAvailable()).toBe(false);
|
expect(checkAvail()).toBe(false);
|
||||||
|
|
||||||
const apiKey = 'test-key';
|
const apiKey = 'test-key';
|
||||||
const result = encryptApiKey(apiKey);
|
const result = encrypt(apiKey);
|
||||||
|
|
||||||
// Should return plaintext when electron is unavailable
|
// Should return plaintext when electron is unavailable
|
||||||
expect(result).toBe(apiKey);
|
expect(result).toBe(apiKey);
|
||||||
@@ -195,21 +266,19 @@ describe('Encryption Utils', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle decryption when safeStorage is null', () => {
|
it('should handle decryption when safeStorage is null', () => {
|
||||||
jest.mock('electron', () => ({
|
mockWindow.require = jest.fn(() => ({ safeStorage: null }));
|
||||||
safeStorage: null
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { decryptApiKey } = require('../src/utils/encryption-utils');
|
const { decryptApiKey: decrypt } = require('../src/utils/encryption-utils');
|
||||||
|
|
||||||
const encrypted = 'encrypted:aW52YWxpZA==';
|
const encrypted = 'encrypted:aW52YWxpZA==';
|
||||||
|
|
||||||
expect(() => decryptApiKey(encrypted)).toThrow('Failed to decrypt API key');
|
expect(() => decrypt(encrypted)).toThrow('Failed to decrypt API key');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log warning when encryption not available on first load', () => {
|
it('should log warning when encryption not available on first load', () => {
|
||||||
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
|
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
|
||||||
|
|
||||||
jest.mock('electron', () => {
|
mockWindow.require = jest.fn(() => {
|
||||||
throw new Error('Module not found');
|
throw new Error('Module not found');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -225,35 +294,32 @@ describe('Encryption Utils', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should gracefully handle plaintext keys when encryption unavailable', () => {
|
it('should gracefully handle plaintext keys when encryption unavailable', () => {
|
||||||
jest.mock('electron', () => ({
|
mockWindow.require = jest.fn(() => ({ safeStorage: null }));
|
||||||
safeStorage: null
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { encryptApiKey, decryptApiKey } = require('../src/utils/encryption-utils');
|
const { encryptApiKey: encrypt, decryptApiKey: decrypt } = require('../src/utils/encryption-utils');
|
||||||
|
|
||||||
const apiKey = 'plain-api-key';
|
const apiKey = 'plain-api-key';
|
||||||
|
|
||||||
// Encrypt should return plaintext
|
// Encrypt should return plaintext
|
||||||
const encrypted = encryptApiKey(apiKey);
|
const encrypted = encrypt(apiKey);
|
||||||
expect(encrypted).toBe(apiKey);
|
expect(encrypted).toBe(apiKey);
|
||||||
|
|
||||||
// Decrypt plaintext should return as-is
|
// Decrypt plaintext should return as-is
|
||||||
const decrypted = decryptApiKey(apiKey);
|
const decrypted = decrypt(apiKey);
|
||||||
expect(decrypted).toBe(apiKey);
|
expect(decrypted).toBe(apiKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should warn when falling back to plaintext storage', () => {
|
it('should warn when falling back to plaintext storage', () => {
|
||||||
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
|
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
|
||||||
|
|
||||||
jest.mock('electron', () => ({
|
const mockStorage = {
|
||||||
safeStorage: {
|
isEncryptionAvailable: jest.fn(() => false)
|
||||||
isEncryptionAvailable: jest.fn(() => false)
|
};
|
||||||
}
|
mockWindow.require = jest.fn(() => ({ safeStorage: mockStorage }));
|
||||||
}));
|
|
||||||
|
|
||||||
const { encryptApiKey } = require('../src/utils/encryption-utils');
|
const { encryptApiKey: encrypt } = require('../src/utils/encryption-utils');
|
||||||
|
|
||||||
encryptApiKey('test-key');
|
encrypt('test-key');
|
||||||
|
|
||||||
expect(consoleSpy).toHaveBeenCalledWith(
|
expect(consoleSpy).toHaveBeenCalledWith(
|
||||||
expect.stringContaining('Encryption not available')
|
expect.stringContaining('Encryption not available')
|
||||||
|
|||||||
@@ -1,18 +1,53 @@
|
|||||||
import { generateApiKey } from '../src/utils/auth-utils';
|
import { generateApiKey } from '../src/utils/auth-utils';
|
||||||
import { encryptApiKey, decryptApiKey } from '../src/utils/encryption-utils';
|
|
||||||
import { DEFAULT_SETTINGS } from '../src/types/settings-types';
|
import { DEFAULT_SETTINGS } from '../src/types/settings-types';
|
||||||
|
|
||||||
// Mock electron
|
// Mock safeStorage implementation
|
||||||
jest.mock('electron', () => ({
|
const mockSafeStorage = {
|
||||||
safeStorage: {
|
isEncryptionAvailable: jest.fn(() => true),
|
||||||
isEncryptionAvailable: jest.fn(() => true),
|
encryptString: jest.fn((data: string) => Buffer.from(`encrypted:${data}`)),
|
||||||
encryptString: jest.fn((data: string) => Buffer.from(`encrypted:${data}`)),
|
decryptString: jest.fn((buffer: Buffer) => buffer.toString().replace('encrypted:', ''))
|
||||||
decryptString: jest.fn((buffer: Buffer) => {
|
};
|
||||||
const str = buffer.toString();
|
|
||||||
return str.replace('encrypted:', '');
|
// Setup window.require mock
|
||||||
})
|
const mockWindowRequire = jest.fn((module: string) => {
|
||||||
|
if (module === 'electron') {
|
||||||
|
return { safeStorage: mockSafeStorage };
|
||||||
}
|
}
|
||||||
}));
|
throw new Error(`Module not found: ${module}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create mock window object for Node environment
|
||||||
|
const mockWindow: Window & { require?: unknown } = {
|
||||||
|
require: mockWindowRequire
|
||||||
|
} as unknown as Window & { require?: unknown };
|
||||||
|
|
||||||
|
// Store original global window
|
||||||
|
const originalWindow = (globalThis as unknown as { window?: unknown }).window;
|
||||||
|
|
||||||
|
// Set up window.require before tests run
|
||||||
|
beforeAll(() => {
|
||||||
|
(globalThis as unknown as { window: typeof mockWindow }).window = mockWindow;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clean up after all tests
|
||||||
|
afterAll(() => {
|
||||||
|
if (originalWindow === undefined) {
|
||||||
|
delete (globalThis as unknown as { window?: unknown }).window;
|
||||||
|
} else {
|
||||||
|
(globalThis as unknown as { window: typeof originalWindow }).window = originalWindow;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Import after mock is set up
|
||||||
|
let encryptApiKey: typeof import('../src/utils/encryption-utils').encryptApiKey;
|
||||||
|
let decryptApiKey: typeof import('../src/utils/encryption-utils').decryptApiKey;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
const encryptionUtils = require('../src/utils/encryption-utils');
|
||||||
|
encryptApiKey = encryptionUtils.encryptApiKey;
|
||||||
|
decryptApiKey = encryptionUtils.decryptApiKey;
|
||||||
|
});
|
||||||
|
|
||||||
describe('Settings Migration', () => {
|
describe('Settings Migration', () => {
|
||||||
describe('API key initialization', () => {
|
describe('API key initialization', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user