66 lines
2.2 KiB
TypeScript
66 lines
2.2 KiB
TypeScript
|
|
import { SecretCryptoService } from '../src/modules/netaclaw/service/secret_crypto.js';
|
||
|
|
|
||
|
|
describe('SecretCryptoService', () => {
|
||
|
|
const originalNetaSecretKey = process.env.NETA_SECRET_KEY;
|
||
|
|
const originalAppSecret = process.env.APP_SECRET;
|
||
|
|
|
||
|
|
beforeEach(() => {
|
||
|
|
process.env.NETA_SECRET_KEY = 'test-secret-key';
|
||
|
|
delete process.env.APP_SECRET;
|
||
|
|
});
|
||
|
|
|
||
|
|
afterEach(() => {
|
||
|
|
if (originalNetaSecretKey === undefined) {
|
||
|
|
delete process.env.NETA_SECRET_KEY;
|
||
|
|
} else {
|
||
|
|
process.env.NETA_SECRET_KEY = originalNetaSecretKey;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (originalAppSecret === undefined) {
|
||
|
|
delete process.env.APP_SECRET;
|
||
|
|
} else {
|
||
|
|
process.env.APP_SECRET = originalAppSecret;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
it('encrypts and decrypts text without embedding plaintext', () => {
|
||
|
|
const service = new SecretCryptoService();
|
||
|
|
|
||
|
|
const encrypted = service.encryptText('mysql-password');
|
||
|
|
|
||
|
|
expect(encrypted).not.toContain('mysql-password');
|
||
|
|
expect(service.decryptText(encrypted)).toBe('mysql-password');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('encrypts and decrypts JSON values', () => {
|
||
|
|
const service = new SecretCryptoService();
|
||
|
|
const value = { username: 'readonly', scopes: ['order.read'], maxRows: 100 };
|
||
|
|
|
||
|
|
const encrypted = service.encryptJson(value);
|
||
|
|
|
||
|
|
expect(encrypted).not.toContain('readonly');
|
||
|
|
expect(service.decryptJson<typeof value>(encrypted)).toEqual(value);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('uses configured jwt secret when secret env vars are absent', () => {
|
||
|
|
delete process.env.NETA_SECRET_KEY;
|
||
|
|
delete process.env.APP_SECRET;
|
||
|
|
const service = new SecretCryptoService();
|
||
|
|
(service as any).jwtSecret = 'configured-jwt-secret';
|
||
|
|
|
||
|
|
const encrypted = service.encryptText('mysql-password');
|
||
|
|
|
||
|
|
expect(service.decryptText(encrypted)).toBe('mysql-password');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects tampered envelopes', () => {
|
||
|
|
const service = new SecretCryptoService();
|
||
|
|
const encrypted = service.encryptText('mysql-password');
|
||
|
|
const envelope = JSON.parse(Buffer.from(encrypted, 'base64').toString('utf8'));
|
||
|
|
envelope.ct = `${envelope.ct.slice(0, -2)}AA`;
|
||
|
|
const tampered = Buffer.from(JSON.stringify(envelope), 'utf8').toString('base64');
|
||
|
|
|
||
|
|
expect(() => service.decryptText(tampered)).toThrow();
|
||
|
|
});
|
||
|
|
});
|