Skip to content

Commit b57f97b

Browse files
committed
chore: fix tests and use tls mode
Ticket: WP-4663
1 parent 8ed9ae6 commit b57f97b

File tree

7 files changed

+147
-107
lines changed

7 files changed

+147
-107
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ dist/
22
node_modules/
33
coverage/
44
.idea/
5-
logs/
5+
logs/

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ Configuration is managed through environment variables:
5151

5252
Both modes use the same TLS configuration variables:
5353

54-
#### Certificate Configuration (choose one approach)
54+
#### TLS Mode
55+
56+
- `TLS_MODE` - Set to either "mtls" or "disabled" (defaults to "mtls" if not set)
57+
58+
#### Certificate Configuration (required when TLS_MODE=mtls)
5559

5660
**Option 1: Certificate Files**
5761

@@ -63,12 +67,11 @@ Both modes use the same TLS configuration variables:
6367
- `TLS_KEY` - Private key content (PEM format)
6468
- `TLS_CERT` - Certificate content (PEM format)
6569

66-
#### mTLS Settings
70+
#### mTLS Settings (when TLS_MODE=mtls)
6771

6872
- `MTLS_REQUEST_CERT` - Request client certificates (default: true)
6973
- `ALLOW_SELF_SIGNED` - Allow self-signed certificates (default: false)
7074
- `MTLS_ALLOWED_CLIENT_FINGERPRINTS` - Comma-separated list of allowed client certificate fingerprints (optional)
71-
- `MASTER_BITGO_EXPRESS_DISABLE_TLS` - Disable TLS completely (default: false)
7275

7376
### Logging and Debug
7477

src/__tests__/config.test.ts

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import { config, isEnclavedConfig, TlsMode } from '../config';
22

33
describe('Configuration', () => {
44
const originalEnv = process.env;
5+
const mockTlsKey = '-----BEGIN PRIVATE KEY-----\nMOCK_KEY\n-----END PRIVATE KEY-----';
6+
const mockTlsCert = '-----BEGIN CERTIFICATE-----\nMOCK_CERT\n-----END CERTIFICATE-----';
57

68
beforeEach(() => {
79
jest.resetModules();
810
process.env = { ...originalEnv };
9-
// Explicitly clear MTLS-related environment variables
10-
delete process.env.MTLS_ENABLED;
11-
delete process.env.MASTER_BITGO_EXPRESS_DISABLE_TLS;
11+
// Clear TLS-related environment variables
12+
delete process.env.TLS_MODE;
1213
});
1314

1415
afterAll(() => {
@@ -27,6 +28,10 @@ describe('Configuration', () => {
2728
describe('Enclaved Mode', () => {
2829
beforeEach(() => {
2930
process.env.APP_MODE = 'enclaved';
31+
process.env.KMS_URL = 'http://localhost:3000';
32+
// Set default TLS certificates
33+
process.env.TLS_KEY = mockTlsKey;
34+
process.env.TLS_CERT = mockTlsCert;
3035
});
3136

3237
it('should use default configuration when no environment variables are set', () => {
@@ -35,45 +40,64 @@ describe('Configuration', () => {
3540
if (isEnclavedConfig(cfg)) {
3641
expect(cfg.port).toBe(3080);
3742
expect(cfg.bind).toBe('localhost');
38-
expect(cfg.tlsMode).toBe(TlsMode.ENABLED);
43+
expect(cfg.tlsMode).toBe(TlsMode.MTLS);
3944
expect(cfg.timeout).toBe(305 * 1000);
45+
expect(cfg.kmsUrl).toBe('http://localhost:3000');
46+
expect(cfg.tlsKey).toBe(mockTlsKey);
47+
expect(cfg.tlsCert).toBe(mockTlsCert);
4048
}
4149
});
4250

4351
it('should read port from environment variable', () => {
44-
process.env.MASTER_BITGO_EXPRESS_PORT = '4000';
52+
process.env.ENCLAVED_EXPRESS_PORT = '4000';
4553
const cfg = config();
4654
expect(isEnclavedConfig(cfg)).toBe(true);
4755
if (isEnclavedConfig(cfg)) {
4856
expect(cfg.port).toBe(4000);
57+
expect(cfg.kmsUrl).toBe('http://localhost:3000');
58+
expect(cfg.tlsKey).toBe(mockTlsKey);
59+
expect(cfg.tlsCert).toBe(mockTlsCert);
4960
}
5061
});
5162

5263
it('should read TLS mode from environment variables', () => {
53-
process.env.MASTER_BITGO_EXPRESS_DISABLE_TLS = 'true';
64+
// Test with TLS disabled
65+
process.env.TLS_MODE = 'disabled';
5466
let cfg = config();
5567
expect(isEnclavedConfig(cfg)).toBe(true);
5668
if (isEnclavedConfig(cfg)) {
5769
expect(cfg.tlsMode).toBe(TlsMode.DISABLED);
70+
expect(cfg.kmsUrl).toBe('http://localhost:3000');
5871
}
5972

60-
process.env.MASTER_BITGO_EXPRESS_DISABLE_TLS = 'false';
61-
process.env.MTLS_ENABLED = 'true';
73+
// Test with mTLS explicitly enabled
74+
process.env.TLS_MODE = 'mtls';
6275
cfg = config();
6376
expect(isEnclavedConfig(cfg)).toBe(true);
6477
if (isEnclavedConfig(cfg)) {
6578
expect(cfg.tlsMode).toBe(TlsMode.MTLS);
79+
expect(cfg.kmsUrl).toBe('http://localhost:3000');
80+
expect(cfg.tlsKey).toBe(mockTlsKey);
81+
expect(cfg.tlsCert).toBe(mockTlsCert);
6682
}
67-
});
6883

69-
it('should throw error when both TLS disabled and mTLS enabled', () => {
70-
process.env.MASTER_BITGO_EXPRESS_DISABLE_TLS = 'true';
71-
process.env.MTLS_ENABLED = 'true';
72-
expect(() => config()).toThrow('Cannot have both TLS disabled and mTLS enabled');
84+
// Test with invalid TLS mode
85+
process.env.TLS_MODE = 'invalid';
86+
expect(() => config()).toThrow('Invalid TLS_MODE: invalid');
87+
88+
// Test with no TLS mode (should default to MTLS)
89+
delete process.env.TLS_MODE;
90+
cfg = config();
91+
expect(isEnclavedConfig(cfg)).toBe(true);
92+
if (isEnclavedConfig(cfg)) {
93+
expect(cfg.tlsMode).toBe(TlsMode.MTLS);
94+
expect(cfg.kmsUrl).toBe('http://localhost:3000');
95+
expect(cfg.tlsKey).toBe(mockTlsKey);
96+
expect(cfg.tlsCert).toBe(mockTlsCert);
97+
}
7398
});
7499

75100
it('should read mTLS settings from environment variables', () => {
76-
process.env.MTLS_ENABLED = 'true';
77101
process.env.MTLS_REQUEST_CERT = 'true';
78102
process.env.MTLS_REJECT_UNAUTHORIZED = 'true';
79103
process.env.MTLS_ALLOWED_CLIENT_FINGERPRINTS = 'ABC123,DEF456';
@@ -82,8 +106,10 @@ describe('Configuration', () => {
82106
expect(isEnclavedConfig(cfg)).toBe(true);
83107
if (isEnclavedConfig(cfg)) {
84108
expect(cfg.mtlsRequestCert).toBe(true);
85-
expect(cfg.mtlsRejectUnauthorized).toBe(true);
86109
expect(cfg.mtlsAllowedClientFingerprints).toEqual(['ABC123', 'DEF456']);
110+
expect(cfg.kmsUrl).toBe('http://localhost:3000');
111+
expect(cfg.tlsKey).toBe(mockTlsKey);
112+
expect(cfg.tlsCert).toBe(mockTlsCert);
87113
}
88114
});
89115
});

src/config.ts

Lines changed: 69 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,22 @@ const defaultEnclavedConfig: EnclavedConfig = {
5757
};
5858

5959
function determineTlsMode(): TlsMode {
60-
const disableTls = readEnvVar('MASTER_BITGO_EXPRESS_DISABLE_TLS') === 'true';
61-
if (disableTls) return TlsMode.DISABLED;
62-
return TlsMode.MTLS;
60+
const tlsMode = readEnvVar('TLS_MODE')?.toLowerCase();
61+
62+
if (!tlsMode) {
63+
logger.warn('TLS_MODE not set, defaulting to MTLS. Set TLS_MODE=disabled to disable TLS.');
64+
return TlsMode.MTLS;
65+
}
66+
67+
if (tlsMode === 'disabled') {
68+
return TlsMode.DISABLED;
69+
}
70+
71+
if (tlsMode === 'mtls') {
72+
return TlsMode.MTLS;
73+
}
74+
75+
throw new Error(`Invalid TLS_MODE: ${tlsMode}. Must be either "disabled" or "mtls"`);
6376
}
6477

6578
function enclavedEnvConfig(): Partial<EnclavedConfig> {
@@ -129,33 +142,36 @@ function configureEnclavedMode(): EnclavedConfig {
129142
const env = enclavedEnvConfig();
130143
let config = mergeEnclavedConfigs(env);
131144

132-
// Handle file loading for TLS certificates
133-
if (!config.tlsKey && config.keyPath) {
134-
try {
135-
config = { ...config, tlsKey: fs.readFileSync(config.keyPath, 'utf-8') };
136-
logger.info(`Successfully loaded TLS private key from file: ${config.keyPath}`);
137-
} catch (e) {
138-
const err = e instanceof Error ? e : new Error(String(e));
139-
throw new Error(`Failed to read TLS key from keyPath: ${err.message}`);
145+
// Only load certificates if TLS is enabled
146+
if (config.tlsMode !== TlsMode.DISABLED) {
147+
// Handle file loading for TLS certificates
148+
if (!config.tlsKey && config.keyPath) {
149+
try {
150+
config = { ...config, tlsKey: fs.readFileSync(config.keyPath, 'utf-8') };
151+
logger.info(`Successfully loaded TLS private key from file: ${config.keyPath}`);
152+
} catch (e) {
153+
const err = e instanceof Error ? e : new Error(String(e));
154+
throw new Error(`Failed to read TLS key from keyPath: ${err.message}`);
155+
}
156+
} else if (config.tlsKey) {
157+
logger.debug('Using TLS private key from environment variable');
140158
}
141-
} else if (config.tlsKey) {
142-
logger.debug('Using TLS private key from environment variable');
143-
}
144159

145-
if (!config.tlsCert && config.crtPath) {
146-
try {
147-
config = { ...config, tlsCert: fs.readFileSync(config.crtPath, 'utf-8') };
148-
logger.info(`Successfully loaded TLS certificate from file: ${config.crtPath}`);
149-
} catch (e) {
150-
const err = e instanceof Error ? e : new Error(String(e));
151-
throw new Error(`Failed to read TLS certificate from crtPath: ${err.message}`);
160+
if (!config.tlsCert && config.crtPath) {
161+
try {
162+
config = { ...config, tlsCert: fs.readFileSync(config.crtPath, 'utf-8') };
163+
logger.info(`Successfully loaded TLS certificate from file: ${config.crtPath}`);
164+
} catch (e) {
165+
const err = e instanceof Error ? e : new Error(String(e));
166+
throw new Error(`Failed to read TLS certificate from crtPath: ${err.message}`);
167+
}
168+
} else if (config.tlsCert) {
169+
logger.debug('Using TLS certificate from environment variable');
152170
}
153-
} else if (config.tlsCert) {
154-
logger.debug('Using TLS certificate from environment variable');
155-
}
156171

157-
// Validate that certificates are properly loaded when TLS is enabled
158-
validateTlsCertificates(config);
172+
// Validate that certificates are properly loaded when TLS is enabled
173+
validateTlsCertificates(config);
174+
}
159175

160176
return config;
161177
}
@@ -289,32 +305,38 @@ export function configureMasterExpressMode(): MasterExpressConfig {
289305
}
290306
config = { ...config, ...updates };
291307

292-
// Handle file loading for TLS certificates
293-
if (!config.tlsKey && config.keyPath) {
294-
try {
295-
config = { ...config, tlsKey: fs.readFileSync(config.keyPath, 'utf-8') };
296-
logger.info(`Successfully loaded TLS private key from file: ${config.keyPath}`);
297-
} catch (e) {
298-
const err = e instanceof Error ? e : new Error(String(e));
299-
throw new Error(`Failed to read TLS key from keyPath: ${err.message}`);
308+
// Only load certificates if TLS is enabled
309+
if (config.tlsMode !== TlsMode.DISABLED) {
310+
// Handle file loading for TLS certificates
311+
if (!config.tlsKey && config.keyPath) {
312+
try {
313+
config = { ...config, tlsKey: fs.readFileSync(config.keyPath, 'utf-8') };
314+
logger.info(`Successfully loaded TLS private key from file: ${config.keyPath}`);
315+
} catch (e) {
316+
const err = e instanceof Error ? e : new Error(String(e));
317+
throw new Error(`Failed to read TLS key from keyPath: ${err.message}`);
318+
}
319+
} else if (config.tlsKey) {
320+
logger.debug('Using TLS private key from environment variable');
300321
}
301-
} else if (config.tlsKey) {
302-
logger.debug('Using TLS private key from environment variable');
303-
}
304322

305-
if (!config.tlsCert && config.crtPath) {
306-
try {
307-
config = { ...config, tlsCert: fs.readFileSync(config.crtPath, 'utf-8') };
308-
logger.info(`Successfully loaded TLS certificate from file: ${config.crtPath}`);
309-
} catch (e) {
310-
const err = e instanceof Error ? e : new Error(String(e));
311-
throw new Error(`Failed to read TLS certificate from crtPath: ${err.message}`);
323+
if (!config.tlsCert && config.crtPath) {
324+
try {
325+
config = { ...config, tlsCert: fs.readFileSync(config.crtPath, 'utf-8') };
326+
logger.info(`Successfully loaded TLS certificate from file: ${config.crtPath}`);
327+
} catch (e) {
328+
const err = e instanceof Error ? e : new Error(String(e));
329+
throw new Error(`Failed to read TLS certificate from crtPath: ${err.message}`);
330+
}
331+
} else if (config.tlsCert) {
332+
logger.debug('Using TLS certificate from environment variable');
312333
}
313-
} else if (config.tlsCert) {
314-
logger.debug('Using TLS certificate from environment variable');
334+
335+
// Validate that certificates are properly loaded when TLS is enabled
336+
validateTlsCertificates(config);
315337
}
316338

317-
// Handle cert loading
339+
// Handle cert loading for Enclaved Express (always required for Master Express)
318340
if (config.enclavedExpressCert) {
319341
try {
320342
if (fs.existsSync(config.enclavedExpressCert)) {
@@ -337,9 +359,6 @@ export function configureMasterExpressMode(): MasterExpressConfig {
337359
}
338360
}
339361

340-
// Validate that certificates are properly loaded when TLS is enabled
341-
validateTlsCertificates(config);
342-
343362
// Validate Master Express configuration
344363
validateMasterExpressConfig(config);
345364

src/enclavedApp.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,6 @@ export function startup(config: EnclavedConfig, baseUri: string): () => void {
3939

4040
function isTLS(config: EnclavedConfig): boolean {
4141
const { keyPath, crtPath, tlsKey, tlsCert, tlsMode } = config;
42-
logger.debug('TLS Configuration:', {
43-
tlsMode,
44-
hasKeyPath: Boolean(keyPath),
45-
hasCrtPath: Boolean(crtPath),
46-
hasTlsKey: Boolean(tlsKey),
47-
hasTlsCert: Boolean(tlsCert),
48-
});
4942
if (tlsMode === TlsMode.DISABLED) return false;
5043
return Boolean((keyPath && crtPath) || (tlsKey && tlsCert));
5144
}

src/masterExpressApp.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,6 @@ export function startup(config: MasterExpressConfig, baseUri: string): () => voi
4949

5050
function isTLS(config: MasterExpressConfig): boolean {
5151
const { keyPath, crtPath, tlsKey, tlsCert, tlsMode } = config;
52-
logger.debug('TLS Configuration:', {
53-
tlsMode,
54-
hasKeyPath: Boolean(keyPath),
55-
hasCrtPath: Boolean(crtPath),
56-
hasTlsKey: Boolean(tlsKey),
57-
hasTlsCert: Boolean(tlsCert),
58-
});
5952
if (tlsMode === TlsMode.DISABLED) return false;
6053
return Boolean((keyPath && crtPath) || (tlsKey && tlsCert));
6154
}
@@ -159,13 +152,6 @@ function setupMasterExpressRoutes(app: express.Application, cfg: MasterExpressCo
159152
// Setup common health check routes
160153
setupHealthCheckRoutes(app, 'master express');
161154

162-
logger.debug('TLS Configuration:', {
163-
tlsMode: cfg.tlsMode,
164-
enclavedExpressUrl: cfg.enclavedExpressUrl,
165-
hasCertificate: Boolean(cfg.enclavedExpressCert),
166-
certificateLength: cfg.enclavedExpressCert.length,
167-
});
168-
169155
// Add enclaved express ping route
170156
app.post('/ping/enclavedExpress', async (req, res) => {
171157
try {

0 commit comments

Comments
 (0)