11import 'should' ;
2- import { initConfig , isEnclavedConfig , TlsMode } from '../initConfig' ;
2+ import { initConfig , isEnclavedConfig , isMasterExpressConfig , TlsMode } from '../initConfig' ;
3+ import path from 'path' ;
34
45describe ( 'Configuration' , ( ) => {
56 const originalEnv = process . env ;
67 const mockTlsKey = '-----BEGIN PRIVATE KEY-----\nMOCK_KEY\n-----END PRIVATE KEY-----' ;
78 const mockTlsCert = '-----BEGIN CERTIFICATE-----\nMOCK_CERT\n-----END CERTIFICATE-----' ;
9+ const mockSecuredExpressCert =
10+ '-----BEGIN CERTIFICATE-----\nENCLAVED_EXPRESS_CERT\n-----END CERTIFICATE-----' ;
811
912 beforeEach ( ( ) => {
13+ // Reset to original environment and clear all relevant variables
1014 process . env = { ...originalEnv } ;
11- // Clear TLS-related environment variables
15+ delete process . env . KMS_URL ;
16+ delete process . env . ENCLAVED_EXPRESS_URL ;
17+ delete process . env . ENCLAVED_EXPRESS_CERT ;
1218 delete process . env . TLS_MODE ;
19+ delete process . env . TLS_KEY ;
20+ delete process . env . TLS_CERT ;
21+ delete process . env . MTLS_REQUEST_CERT ;
22+ delete process . env . MTLS_REJECT_UNAUTHORIZED ;
23+ delete process . env . MTLS_ALLOWED_CLIENT_FINGERPRINTS ;
24+ delete process . env . ALLOW_SELF_SIGNED ;
25+ delete process . env . ENCLAVED_EXPRESS_PORT ;
26+ delete process . env . MASTER_EXPRESS_PORT ;
27+ delete process . env . BIND ;
28+ delete process . env . IPC ;
29+ delete process . env . DEBUG_NAMESPACE ;
30+ delete process . env . LOGFILE ;
31+ delete process . env . KEEP_ALIVE_TIMEOUT ;
32+ delete process . env . HEADERS_TIMEOUT ;
33+ delete process . env . BITGO_ENV ;
34+ delete process . env . BITGO_CUSTOM_ROOT_URI ;
35+ delete process . env . BITGO_DISABLE_ENV_CHECK ;
36+ delete process . env . BITGO_AUTH_VERSION ;
37+ delete process . env . BITGO_CUSTOM_BITCOIN_NETWORK ;
38+ delete process . env . TLS_KEY_PATH ;
39+ delete process . env . TLS_CERT_PATH ;
1340 } ) ;
1441
1542 after ( ( ) => {
@@ -32,13 +59,12 @@ describe('Configuration', () => {
3259 describe ( 'Enclaved Mode' , ( ) => {
3360 beforeEach ( ( ) => {
3461 process . env . APP_MODE = 'enclaved' ;
62+ } ) ;
63+
64+ it ( 'should use default configuration when minimal environment variables are set' , ( ) => {
3565 process . env . KMS_URL = 'http://localhost:3000' ;
36- // Set default TLS certificates
3766 process . env . TLS_KEY = mockTlsKey ;
3867 process . env . TLS_CERT = mockTlsCert ;
39- } ) ;
40-
41- it ( 'should use default configuration when no environment variables are set' , ( ) => {
4268 const cfg = initConfig ( ) ;
4369 isEnclavedConfig ( cfg ) . should . be . true ( ) ;
4470 if ( isEnclavedConfig ( cfg ) ) {
@@ -54,6 +80,9 @@ describe('Configuration', () => {
5480
5581 it ( 'should read port from environment variable' , ( ) => {
5682 process . env . ENCLAVED_EXPRESS_PORT = '4000' ;
83+ process . env . KMS_URL = 'http://localhost:3000' ;
84+ process . env . TLS_KEY = mockTlsKey ;
85+ process . env . TLS_CERT = mockTlsCert ;
5786 const cfg = initConfig ( ) ;
5887 isEnclavedConfig ( cfg ) . should . be . true ( ) ;
5988 if ( isEnclavedConfig ( cfg ) ) {
@@ -65,6 +94,10 @@ describe('Configuration', () => {
6594 } ) ;
6695
6796 it ( 'should read TLS mode from environment variables' , ( ) => {
97+ process . env . KMS_URL = 'http://localhost:3000' ;
98+ process . env . TLS_KEY = mockTlsKey ;
99+ process . env . TLS_CERT = mockTlsCert ;
100+
68101 // Test with TLS disabled
69102 process . env . TLS_MODE = 'disabled' ;
70103 let cfg = initConfig ( ) ;
@@ -104,6 +137,9 @@ describe('Configuration', () => {
104137 } ) ;
105138
106139 it ( 'should read mTLS settings from environment variables' , ( ) => {
140+ process . env . KMS_URL = 'http://localhost:3000' ;
141+ process . env . TLS_KEY = mockTlsKey ;
142+ process . env . TLS_CERT = mockTlsCert ;
107143 process . env . MTLS_REQUEST_CERT = 'true' ;
108144 process . env . MTLS_REJECT_UNAUTHORIZED = 'true' ;
109145 process . env . MTLS_ALLOWED_CLIENT_FINGERPRINTS = 'ABC123,DEF456' ;
@@ -118,5 +154,216 @@ describe('Configuration', () => {
118154 cfg . tlsCert ! . should . equal ( mockTlsCert ) ;
119155 }
120156 } ) ;
157+
158+ it ( 'should throw error when KMS_URL is not set' , ( ) => {
159+ delete process . env . KMS_URL ;
160+ ( ( ) => initConfig ( ) ) . should . throw (
161+ 'KMS_URL environment variable is required and cannot be empty' ,
162+ ) ;
163+ } ) ;
164+
165+ it ( 'should throw error when KMS_URL is empty' , ( ) => {
166+ process . env . KMS_URL = '' ;
167+ ( ( ) => initConfig ( ) ) . should . throw (
168+ 'KMS_URL environment variable is required and cannot be empty' ,
169+ ) ;
170+ } ) ;
171+
172+ it ( 'should succeed when TLS certificates are not set for disabled TLS mode' , ( ) => {
173+ process . env . KMS_URL = 'http://localhost:3000' ;
174+ process . env . TLS_MODE = 'disabled' ;
175+ delete process . env . TLS_KEY ;
176+ delete process . env . TLS_CERT ;
177+ const cfg = initConfig ( ) ;
178+ isEnclavedConfig ( cfg ) . should . be . true ( ) ;
179+ if ( isEnclavedConfig ( cfg ) ) {
180+ cfg . tlsMode . should . equal ( TlsMode . DISABLED ) ;
181+ cfg . kmsUrl . should . equal ( 'http://localhost:3000' ) ;
182+ }
183+ } ) ;
184+
185+ it ( 'should throw error when TLS certificates are not set for MTLS mode' , ( ) => {
186+ process . env . KMS_URL = 'http://localhost:3000' ;
187+ process . env . TLS_MODE = 'mtls' ;
188+ delete process . env . TLS_KEY ;
189+ delete process . env . TLS_CERT ;
190+ ( ( ) => initConfig ( ) ) . should . throw ( ) ;
191+ } ) ;
192+ } ) ;
193+
194+ describe ( 'Master Express Mode' , ( ) => {
195+ beforeEach ( ( ) => {
196+ process . env . APP_MODE = 'master-express' ;
197+ process . env . ENCLAVED_EXPRESS_URL = 'http://localhost:3080' ;
198+ process . env . ENCLAVED_EXPRESS_CERT = path . resolve (
199+ __dirname ,
200+ 'mocks/certs/enclaved-express-cert.pem' ,
201+ ) ;
202+ process . env . TLS_CERT_PATH = path . resolve ( __dirname , 'mocks/certs/test-ssl-cert.pem' ) ;
203+ process . env . TLS_KEY_PATH = path . resolve ( __dirname , 'mocks/certs/test-ssl-key.pem' ) ;
204+ } ) ;
205+
206+ it ( 'should use default configuration when minimal environment variables are set' , ( ) => {
207+ const cfg = initConfig ( ) ;
208+ isMasterExpressConfig ( cfg ) . should . be . true ( ) ;
209+ if ( isMasterExpressConfig ( cfg ) ) {
210+ cfg . port . should . equal ( 3081 ) ;
211+ cfg . bind . should . equal ( 'localhost' ) ;
212+ cfg . tlsMode . should . equal ( TlsMode . MTLS ) ;
213+ cfg . timeout . should . equal ( 305 * 1000 ) ;
214+ cfg . enclavedExpressUrl . should . equal ( 'https://localhost:3080' ) ;
215+ cfg . env . should . equal ( 'test' ) ;
216+ }
217+ } ) ;
218+
219+ it ( 'should read port from environment variable' , ( ) => {
220+ process . env . MASTER_EXPRESS_PORT = '4001' ;
221+ const cfg = initConfig ( ) ;
222+ isMasterExpressConfig ( cfg ) . should . be . true ( ) ;
223+ if ( isMasterExpressConfig ( cfg ) ) {
224+ cfg . port . should . equal ( 4001 ) ;
225+ cfg . enclavedExpressUrl . should . equal ( 'https://localhost:3080' ) ;
226+ }
227+ } ) ;
228+
229+ it ( 'should read BitGo environment settings' , ( ) => {
230+ process . env . BITGO_ENV = 'prod' ;
231+ process . env . BITGO_CUSTOM_ROOT_URI = 'https://custom.bitgo.com' ;
232+ process . env . BITGO_DISABLE_ENV_CHECK = 'false' ;
233+ process . env . BITGO_AUTH_VERSION = '3' ;
234+ process . env . BITGO_CUSTOM_BITCOIN_NETWORK = 'testnet' ;
235+
236+ const cfg = initConfig ( ) ;
237+ isMasterExpressConfig ( cfg ) . should . be . true ( ) ;
238+ if ( isMasterExpressConfig ( cfg ) ) {
239+ cfg . env . should . equal ( 'prod' ) ;
240+ cfg . customRootUri ! . should . equal ( 'https://custom.bitgo.com' ) ;
241+ cfg . disableEnvCheck ! . should . be . false ( ) ;
242+ cfg . authVersion ! . should . equal ( 3 ) ;
243+ cfg . customBitcoinNetwork ! . should . equal ( 'testnet' ) ;
244+ }
245+ } ) ;
246+
247+ it ( 'should handle TLS mode disabled configuration' , ( ) => {
248+ // Test with TLS disabled
249+ process . env . TLS_MODE = 'disabled' ;
250+ delete process . env . ENCLAVED_EXPRESS_CERT ;
251+ delete process . env . TLS_KEY_PATH ;
252+ delete process . env . TLS_CERT_PATH ;
253+ delete process . env . TLS_KEY ;
254+ delete process . env . TLS_CERT ;
255+
256+ const cfg = initConfig ( ) ;
257+ isMasterExpressConfig ( cfg ) . should . be . true ( ) ;
258+ if ( isMasterExpressConfig ( cfg ) ) {
259+ cfg . tlsMode . should . equal ( TlsMode . DISABLED ) ;
260+ cfg . enclavedExpressUrl . should . equal ( 'http://localhost:3080' ) ;
261+ }
262+ } ) ;
263+
264+ it ( 'should read mTLS settings from environment variables' , ( ) => {
265+ process . env . MTLS_REQUEST_CERT = 'true' ;
266+ process . env . ALLOW_SELF_SIGNED = 'true' ;
267+ process . env . MTLS_ALLOWED_CLIENT_FINGERPRINTS = 'ABC123,DEF456' ;
268+
269+ const cfg = initConfig ( ) ;
270+ isMasterExpressConfig ( cfg ) . should . be . true ( ) ;
271+ if ( isMasterExpressConfig ( cfg ) ) {
272+ cfg . mtlsRequestCert ! . should . be . true ( ) ;
273+ cfg . allowSelfSigned ! . should . be . true ( ) ;
274+ cfg . mtlsAllowedClientFingerprints ! . should . deepEqual ( [ 'ABC123' , 'DEF456' ] ) ;
275+ cfg . enclavedExpressUrl . should . equal ( 'https://localhost:3080' ) ;
276+ }
277+ } ) ;
278+
279+ it ( 'should throw error when ENCLAVED_EXPRESS_URL is not set' , ( ) => {
280+ delete process . env . ENCLAVED_EXPRESS_URL ;
281+ ( ( ) => initConfig ( ) ) . should . throw (
282+ 'ENCLAVED_EXPRESS_URL environment variable is required and cannot be empty' ,
283+ ) ;
284+ } ) ;
285+
286+ it ( 'should suceed if mTLS mode is enabled but mTLS_REQUEST_CERT is false' , ( ) => {
287+ process . env . MTLS_REQUEST_CERT = 'false' ;
288+ const cfg = initConfig ( ) ;
289+ isMasterExpressConfig ( cfg ) . should . be . true ( ) ;
290+ if ( isMasterExpressConfig ( cfg ) ) {
291+ cfg . mtlsRequestCert ! . should . be . false ( ) ;
292+ }
293+
294+ it ( 'should throw error when ENCLAVED_EXPRESS_URL is empty' , ( ) => {
295+ process . env . ENCLAVED_EXPRESS_URL = '' ;
296+ ( ( ) => initConfig ( ) ) . should . throw (
297+ 'ENCLAVED_EXPRESS_URL environment variable is required and cannot be empty' ,
298+ ) ;
299+ } ) ;
300+
301+ it ( 'should throw error when ENCLAVED_EXPRESS_CERT is not set for MTLS mode' , ( ) => {
302+ process . env . TLS_MODE = 'mtls' ;
303+ delete process . env . ENCLAVED_EXPRESS_CERT ;
304+ ( ( ) => initConfig ( ) ) . should . throw (
305+ 'ENCLAVED_EXPRESS_CERT environment variable is required for MTLS mode.' ,
306+ ) ;
307+ } ) ;
308+
309+ it ( 'should succeed when ENCLAVED_EXPRESS_CERT is not set for disabled TLS mode' , ( ) => {
310+ process . env . ENCLAVED_EXPRESS_URL = 'http://localhost:3080' ;
311+ process . env . TLS_MODE = 'disabled' ;
312+ delete process . env . ENCLAVED_EXPRESS_CERT ;
313+ const cfg = initConfig ( ) ;
314+ isMasterExpressConfig ( cfg ) . should . be . true ( ) ;
315+ if ( isMasterExpressConfig ( cfg ) ) {
316+ cfg . tlsMode . should . equal ( TlsMode . DISABLED ) ;
317+ cfg . enclavedExpressUrl . should . equal ( 'http://localhost:3080' ) ;
318+ cfg . enclavedExpressCert ! . should . equal ( '' ) ;
319+ }
320+ } ) ;
321+
322+ it ( 'should throw error when ENCLAVED_EXPRESS_CERT is not set for default MTLS mode' , ( ) => {
323+ delete process . env . ENCLAVED_EXPRESS_CERT ;
324+ ( ( ) => initConfig ( ) ) . should . throw (
325+ 'ENCLAVED_EXPRESS_CERT environment variable is required for MTLS mode.' ,
326+ ) ;
327+ } ) ;
328+
329+ it ( 'should handle URL protocol conversion correctly' , ( ) => {
330+ process . env . ENCLAVED_EXPRESS_CERT = mockSecuredExpressCert ;
331+
332+ // Test with URL that already has protocol
333+ process . env . ENCLAVED_EXPRESS_URL = 'https://enclaved.example.com:3080' ;
334+ let cfg = initConfig ( ) ;
335+ isMasterExpressConfig ( cfg ) . should . be . true ( ) ;
336+ if ( isMasterExpressConfig ( cfg ) ) {
337+ cfg . enclavedExpressUrl . should . equal ( 'https://enclaved.example.com:3080' ) ;
338+ }
339+
340+ // Test with URL without protocol (should add https for MTLS)
341+ process . env . ENCLAVED_EXPRESS_URL = 'enclaved.example.com:3080' ;
342+ cfg = initConfig ( ) ;
343+ isMasterExpressConfig ( cfg ) . should . be . true ( ) ;
344+ if ( isMasterExpressConfig ( cfg ) ) {
345+ cfg . enclavedExpressUrl . should . equal ( 'https://enclaved.example.com:3080' ) ;
346+ }
347+
348+ // Test with URL without protocol and disabled TLS (should add http)
349+ process . env . ENCLAVED_EXPRESS_URL = 'enclaved.example.com:3080' ;
350+ process . env . TLS_MODE = 'disabled' ;
351+ cfg = initConfig ( ) ;
352+ isMasterExpressConfig ( cfg ) . should . be . true ( ) ;
353+ if ( isMasterExpressConfig ( cfg ) ) {
354+ cfg . enclavedExpressUrl . should . equal ( 'http://enclaved.example.com:3080' ) ;
355+ }
356+ } ) ;
357+
358+ it ( 'should handle custom BitGo root URI protocol conversion' , ( ) => {
359+ process . env . ENCLAVED_EXPRESS_URL = 'http://localhost:3080' ;
360+ process . env . ENCLAVED_EXPRESS_CERT = mockSecuredExpressCert ;
361+ process . env . BITGO_CUSTOM_ROOT_URI = 'bitgo.example.com' ;
362+ const cfg = initConfig ( ) ;
363+ isMasterExpressConfig ( cfg ) . should . be . true ( ) ;
364+ if ( isMasterExpressConfig ( cfg ) ) {
365+ cfg . customRootUri ! . should . equal ( 'https://bitgo.example.com' ) ;
366+ }
367+ } ) ;
121368 } ) ;
122369} ) ;
0 commit comments