@@ -133,6 +133,7 @@ describe('Activation State Machine', () => {
133133 canActivate : true ,
134134 shbcCCMComplete : false ,
135135 shbcACMComplete : false ,
136+ tlsTunnelCCMComplete : false ,
136137 message : '' ,
137138 clientId,
138139 xmlMessage : '' ,
@@ -259,7 +260,11 @@ describe('Activation State Machine', () => {
259260 tls : fromPromise ( async ( { input } ) => await Promise . resolve ( { clientId } ) ) ,
260261 cira : fromPromise ( async ( { input } ) => await Promise . resolve ( { clientId } ) ) ,
261262 setMEBxPassword : fromPromise ( async ( { input } ) => await Promise . resolve ( { clientId } ) ) ,
262- initializeTLSTunnel : fromPromise ( async ( ) => await Promise . resolve ( true ) )
263+ initializeTLSTunnel : fromPromise ( async ( ) => await Promise . resolve ( true ) ) ,
264+ saveTlsTunnelCerts : fromPromise ( async ( ) => await Promise . resolve ( true ) ) ,
265+ signalPortSwitch : fromPromise ( async ( ) => await Promise . resolve ( true ) ) ,
266+ initializeTlsTunnelConnection : fromPromise ( async ( ) => await Promise . resolve ( true ) ) ,
267+ tlsTunnelProvisioning : fromPromise ( async ( ) => await Promise . resolve ( { clientId } ) )
263268 } ,
264269 actions : {
265270 'Read General Settings' : ( ) => { } ,
@@ -2097,4 +2102,120 @@ describe('Activation State Machine', () => {
20972102 expect ( devices [ clientId ] . tlsTunnelManager ) . toBeUndefined ( )
20982103 } )
20992104 } )
2105+
2106+ describe ( 'TLS Tunnel Activation' , ( ) => {
2107+ describe ( 'saveTlsTunnelCerts' , ( ) => {
2108+ it ( 'should save certs to vault for ACM' , async ( ) => {
2109+ const clientObj = devices [ clientId ]
2110+ clientObj . uuid = 'test-uuid'
2111+ clientObj . amtPassword = 'testAMTpw'
2112+ clientObj . mebxPassword = 'testMEBXpw'
2113+ clientObj . action = ClientAction . ADMINCTLMODE
2114+ clientObj . tls = { rootCertPEM : 'rootCert' , issuedCertPEM : 'issuedCert' } as any
2115+
2116+ const insertSpy = spyOn ( activation . configurator . secretsManager , 'writeSecretWithObject' ) . mockImplementation (
2117+ async ( ) => true
2118+ )
2119+ const result = await activation . saveTlsTunnelCerts ( { input : context } as any )
2120+ expect ( result ) . toBe ( true )
2121+ expect ( insertSpy ) . toHaveBeenCalledWith ( 'devices/test-uuid' , {
2122+ AMT_PASSWORD : 'testAMTpw' ,
2123+ MEBX_PASSWORD : 'testMEBXpw' ,
2124+ TLS_ROOT_CERTIFICATE : 'rootCert' ,
2125+ TLS_ISSUED_CERTIFICATE : 'issuedCert'
2126+ } )
2127+ } )
2128+
2129+ it ( 'should save certs to vault for CCM (mebxPassword null)' , async ( ) => {
2130+ const clientObj = devices [ clientId ]
2131+ clientObj . uuid = 'test-uuid'
2132+ clientObj . amtPassword = 'testAMTpw'
2133+ clientObj . mebxPassword = null
2134+ clientObj . action = ClientAction . CLIENTCTLMODE as any
2135+ clientObj . tls = { rootCertPEM : 'rootCert' , issuedCertPEM : 'issuedCert' } as any
2136+
2137+ const insertSpy = spyOn ( activation . configurator . secretsManager , 'writeSecretWithObject' ) . mockImplementation (
2138+ async ( ) => true
2139+ )
2140+ const result = await activation . saveTlsTunnelCerts ( { input : context } as any )
2141+ expect ( result ) . toBe ( true )
2142+ expect ( insertSpy ) . toHaveBeenCalledWith ( 'devices/test-uuid' , {
2143+ AMT_PASSWORD : 'testAMTpw' ,
2144+ MEBX_PASSWORD : null ,
2145+ TLS_ROOT_CERTIFICATE : 'rootCert' ,
2146+ TLS_ISSUED_CERTIFICATE : 'issuedCert'
2147+ } )
2148+ } )
2149+
2150+ it ( 'should throw when amtPassword is null' , async ( ) => {
2151+ const clientObj = devices [ clientId ]
2152+ clientObj . uuid = 'test-uuid'
2153+ clientObj . amtPassword = null
2154+ clientObj . mebxPassword = 'testMEBXpw'
2155+ clientObj . action = ClientAction . ADMINCTLMODE
2156+
2157+ await expect ( activation . saveTlsTunnelCerts ( { input : context } as any ) ) . rejects . toThrow (
2158+ 'Missing prerequisites for saving TLS tunnel certs'
2159+ )
2160+ } )
2161+
2162+ it ( 'should throw when mebxPassword is null for ACM' , async ( ) => {
2163+ const clientObj = devices [ clientId ]
2164+ clientObj . uuid = 'test-uuid'
2165+ clientObj . amtPassword = 'testAMTpw'
2166+ clientObj . mebxPassword = null
2167+ clientObj . action = ClientAction . ADMINCTLMODE
2168+
2169+ await expect ( activation . saveTlsTunnelCerts ( { input : context } as any ) ) . rejects . toThrow (
2170+ 'Missing prerequisites for saving TLS tunnel certs'
2171+ )
2172+ } )
2173+ } )
2174+
2175+ describe ( 'signalPortSwitch' , ( ) => {
2176+ it ( 'should send port_switch message and resolve on ACK' , async ( ) => {
2177+ const clientObj = devices [ clientId ]
2178+ clientObj . uuid = 'test-uuid'
2179+ clientObj . tls = { rootCertPEM : 'rootCert' } as any
2180+ responseMessageSpy . mockRestore ( )
2181+ sendSpy . mockRestore ( )
2182+ sendSpy = spyOn ( devices [ clientId ] . ClientSocket , 'send' ) . mockReturnValue ( )
2183+
2184+ const promise = activation . signalPortSwitch ( { input : context } as any )
2185+
2186+ // Simulate PORT_SWITCH_ACK by resolving the pending promise
2187+ await new Promise ( ( r ) => setTimeout ( r , 10 ) )
2188+ clientObj . resolve ( 'port_switch_ack' )
2189+
2190+ const result = await promise
2191+ expect ( result ) . toBe ( true )
2192+ expect ( sendSpy ) . toHaveBeenCalled ( )
2193+ } )
2194+
2195+ it ( 'should reject on ACK timeout' , async ( ) => {
2196+ jest . useFakeTimers ( )
2197+ const clientObj = devices [ clientId ]
2198+ clientObj . uuid = 'test-uuid'
2199+ clientObj . tls = { rootCertPEM : 'rootCert' } as any
2200+ Environment . Config . delay_tls_timer = 1
2201+
2202+ const promise = activation . signalPortSwitch ( { input : context } as any )
2203+ jest . advanceTimersByTime ( 61 * 1000 + 1 )
2204+
2205+ await expect ( promise ) . rejects . toThrow ( 'PORT_SWITCH_ACK timeout' )
2206+ jest . useRealTimers ( )
2207+ } )
2208+ } )
2209+
2210+ describe ( 'initializeTlsTunnelConnection' , ( ) => {
2211+ it ( 'should set tlsEnforced on the client object' , ( ) => {
2212+ // initializeTlsTunnelConnection creates a TLSTunnelManager and sets tlsEnforced = true on success.
2213+ // We verify that the state machine correctly routes failures via onError by checking the state definition.
2214+ const states = activation . machine . config . states as any
2215+ expect ( states . INIT_TLS_TUNNEL_CONNECTION ) . toBeDefined ( )
2216+ expect ( states . INIT_TLS_TUNNEL_CONNECTION . invoke . onError . target ) . toBe ( 'FAILED' )
2217+ expect ( states . INIT_TLS_TUNNEL_CONNECTION . invoke . src ) . toBe ( 'initializeTlsTunnelConnection' )
2218+ } )
2219+ } )
2220+ } )
21002221} )
0 commit comments