@@ -503,3 +503,124 @@ func getMockNotificationReceiver(conf config.SyncConfig, returnError bool, msg .
503503 return dataChan , nil
504504 }
505505}
506+
507+ func (suite * NotificationTestSuite ) TestSecureTokenParsing () {
508+ conf := config .NewDefaultConfig ()
509+
510+ testCases := []struct {
511+ name string
512+ sdkKeyHeader string
513+ expectedSDKKey string
514+ description string
515+ }{
516+ {
517+ name : "StandardSDKKey" ,
518+ sdkKeyHeader : "normal_sdk_key_123" ,
519+ expectedSDKKey : "normal_sdk_key_123" ,
520+ description : "Standard SDK key without secure token should remain unchanged" ,
521+ },
522+ {
523+ name : "SecureTokenFormat" ,
524+ sdkKeyHeader : "sdk_key_123:api_key_456" ,
525+ expectedSDKKey : "sdk_key_123" ,
526+ description : "SDK key with secure token should extract only the SDK key portion" ,
527+ },
528+ {
529+ name : "MultipleColons" ,
530+ sdkKeyHeader : "sdk_key:api_key:extra_part" ,
531+ expectedSDKKey : "sdk_key" ,
532+ description : "Multiple colons should split at first colon only" ,
533+ },
534+ {
535+ name : "EmptySDKKey" ,
536+ sdkKeyHeader : ":api_key_456" ,
537+ expectedSDKKey : "" ,
538+ description : "Empty SDK key portion should result in empty string" ,
539+ },
540+ {
541+ name : "EmptyAPIKey" ,
542+ sdkKeyHeader : "sdk_key_123:" ,
543+ expectedSDKKey : "sdk_key_123" ,
544+ description : "Empty API key portion should extract SDK key" ,
545+ },
546+ {
547+ name : "ColonOnly" ,
548+ sdkKeyHeader : ":" ,
549+ expectedSDKKey : "" ,
550+ description : "Colon only should result in empty SDK key" ,
551+ },
552+ {
553+ name : "EmptyHeader" ,
554+ sdkKeyHeader : "" ,
555+ expectedSDKKey : "" ,
556+ description : "Empty header should remain empty" ,
557+ },
558+ }
559+
560+ for _ , tc := range testCases {
561+ suite .Run (tc .name , func () {
562+ // Create a mock notification receiver that captures the SDK key
563+ var capturedSDKKey string
564+ mockReceiver := func (ctx context.Context ) (<- chan syncer.Event , error ) {
565+ capturedSDKKey = ctx .Value (SDKKey ).(string )
566+ dataChan := make (chan syncer.Event )
567+ close (dataChan ) // Close immediately as we don't need events
568+ return dataChan , nil
569+ }
570+
571+ // Setup handler
572+ suite .mux .Get ("/test-notifications" , NotificationEventStreamHandler (mockReceiver ))
573+
574+ // Create request with SDK key header
575+ req := httptest .NewRequest ("GET" , "/test-notifications" , nil )
576+ if tc .sdkKeyHeader != "" {
577+ req .Header .Set (middleware .OptlySDKHeader , tc .sdkKeyHeader )
578+ }
579+ rec := httptest .NewRecorder ()
580+
581+ // Execute request
582+ suite .mux .ServeHTTP (rec , req )
583+
584+ // Verify SDK key was parsed correctly
585+ suite .Equal (tc .expectedSDKKey , capturedSDKKey , tc .description )
586+ })
587+ }
588+ }
589+
590+ func (suite * NotificationTestSuite ) TestSecureTokenParsingIntegration () {
591+ // Test that secure token parsing works end-to-end with actual notification flow
592+ conf := config .NewDefaultConfig ()
593+
594+ // Test with secure token format
595+ req := httptest .NewRequest ("GET" , "/notifications/event-stream" , nil )
596+ req .Header .Set (middleware .OptlySDKHeader , "test_sdk_key:test_api_key" )
597+ rec := httptest .NewRecorder ()
598+
599+ // Create a mock receiver that verifies the SDK key context
600+ mockReceiver := func (ctx context.Context ) (<- chan syncer.Event , error ) {
601+ sdkKey := ctx .Value (SDKKey ).(string )
602+ suite .Equal ("test_sdk_key" , sdkKey , "SDK key should be extracted from secure token format" )
603+
604+ dataChan := make (chan syncer.Event , 1 )
605+ // Send a test event
606+ dataChan <- syncer.Event {
607+ Type : notification .Decision ,
608+ Message : map [string ]string {"test" : "event" },
609+ }
610+ close (dataChan )
611+ return dataChan , nil
612+ }
613+
614+ suite .mux .Get ("/test-secure-notifications" , NotificationEventStreamHandler (mockReceiver ))
615+
616+ // Create cancelable context for SSE
617+ ctx , cancel := context .WithTimeout (req .Context (), 1 * time .Second )
618+ defer cancel ()
619+
620+ suite .mux .ServeHTTP (rec , req .WithContext (ctx ))
621+
622+ // Verify response
623+ suite .Equal (http .StatusOK , rec .Code )
624+ response := rec .Body .String ()
625+ suite .Contains (response , `data: {"test":"event"}` , "Should receive the test event" )
626+ }
0 commit comments