diff --git a/internal/commands/auth.go b/internal/commands/auth.go index 832fa66bc..362b74763 100644 --- a/internal/commands/auth.go +++ b/internal/commands/auth.go @@ -5,6 +5,7 @@ import ( "log" "github.com/MakeNowJust/heredoc" + "github.com/checkmarx/ast-cli/internal/logger" "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" "github.com/google/uuid" @@ -38,7 +39,7 @@ type ClientCreated struct { Secret string `json:"secret"` } -func NewAuthCommand(authWrapper wrappers.AuthWrapper) *cobra.Command { +func NewAuthCommand(authWrapper wrappers.AuthWrapper, telemetryWrapper wrappers.TelemetryWrapper) *cobra.Command { authCmd := &cobra.Command{ Use: "auth", Short: "Validate authentication and create OAuth2 credentials", @@ -110,13 +111,13 @@ func NewAuthCommand(authWrapper wrappers.AuthWrapper) *cobra.Command { `, ), }, - RunE: validLogin(), + RunE: validLogin(telemetryWrapper), } authCmd.AddCommand(createClientCmd, validLoginCmd) return authCmd } -func validLogin() func(cmd *cobra.Command, args []string) error { +func validLogin(telemetryWrapper wrappers.TelemetryWrapper) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { clientID := viper.GetString(params.AccessKeyIDConfigKey) clientSecret := viper.GetString(params.AccessKeySecretConfigKey) @@ -125,6 +126,19 @@ func validLogin() func(cmd *cobra.Command, args []string) error { authWrapper := wrappers.NewAuthHTTPWrapper() authWrapper.SetPath(viper.GetString(params.ScansPathKey)) err := authWrapper.ValidateLogin() + + uniqueID := wrappers.GetUniqueID() + if uniqueID != "" { + telemetryErr := telemetryWrapper.SendAIDataToLog(&wrappers.DataForAITelemetry{ + UniqueID: uniqueID, + Type: "authentication", + SubType: "authentication", + }) + if telemetryErr != nil { + logger.PrintIfVerbose("Failed to send telemetry data: " + telemetryErr.Error()) + } + } + if err != nil { return errors.Errorf("%s", err) } diff --git a/internal/commands/root.go b/internal/commands/root.go index e2c531af7..453070073 100644 --- a/internal/commands/root.go +++ b/internal/commands/root.go @@ -205,7 +205,7 @@ func NewAstCLI( ) versionCmd := util.NewVersionCommand() - authCmd := NewAuthCommand(authWrapper) + authCmd := NewAuthCommand(authWrapper, telemetryWrapper) utilsCmd := util.NewUtilsCommand( gitHubWrapper, azureWrapper, diff --git a/internal/commands/telemetry.go b/internal/commands/telemetry.go index 3b5bbefe0..b858454ac 100644 --- a/internal/commands/telemetry.go +++ b/internal/commands/telemetry.go @@ -58,7 +58,7 @@ func runTelemetryAI(telemetryWrapper wrappers.TelemetryWrapper) func(*cobra.Comm scanType, _ := cmd.Flags().GetString("scan-type") status, _ := cmd.Flags().GetString("status") totalCount, _ := cmd.Flags().GetInt("total-count") - + uniqueID := wrappers.GetUniqueID() err := telemetryWrapper.SendAIDataToLog(&wrappers.DataForAITelemetry{ AIProvider: aiProvider, ProblemSeverity: problemSeverity, @@ -69,6 +69,7 @@ func runTelemetryAI(telemetryWrapper wrappers.TelemetryWrapper) func(*cobra.Comm ScanType: scanType, Status: status, TotalCount: totalCount, + UniqueID: uniqueID, }) if err != nil { diff --git a/internal/commands/util/tenant.go b/internal/commands/util/tenant.go index 0b7447630..07b3ac16c 100644 --- a/internal/commands/util/tenant.go +++ b/internal/commands/util/tenant.go @@ -11,7 +11,7 @@ import ( "github.com/spf13/cobra" ) -func NewTenantConfigurationCommand(wrapper wrappers.TenantConfigurationWrapper, jwtWrapper wrappers.JWTWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper) *cobra.Command { +func NewTenantConfigurationCommand(wrapper wrappers.TenantConfigurationWrapper, jwtWrapper wrappers.JWTWrapper) *cobra.Command { cmd := &cobra.Command{ Use: "tenant", Short: "Shows the tenant settings", @@ -27,7 +27,7 @@ func NewTenantConfigurationCommand(wrapper wrappers.TenantConfigurationWrapper, `, ), }, - RunE: runTenantCmd(wrapper, jwtWrapper, featureFlagsWrapper), + RunE: runTenantCmd(wrapper, jwtWrapper), } cmd.PersistentFlags().String( params.FormatFlag, @@ -40,7 +40,7 @@ func NewTenantConfigurationCommand(wrapper wrappers.TenantConfigurationWrapper, return cmd } -func runTenantCmd(wrapper wrappers.TenantConfigurationWrapper, jwtWrapper wrappers.JWTWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper) func(cmd *cobra.Command, args []string) error { +func runTenantCmd(wrapper wrappers.TenantConfigurationWrapper, jwtWrapper wrappers.JWTWrapper) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { tenantConfigurationResponse, errorModel, err := wrapper.GetTenantConfiguration() if err != nil { @@ -53,7 +53,7 @@ func runTenantCmd(wrapper wrappers.TenantConfigurationWrapper, jwtWrapper wrappe format, _ := cmd.Flags().GetString(params.FormatFlag) tenantConfigurationResponseView := toTenantConfigurationResponseView(tenantConfigurationResponse) - licenseDetails, err := jwtWrapper.GetLicenseDetails(featureFlagsWrapper) + licenseDetails, err := jwtWrapper.GetLicenseDetails() if err == nil { tenantConfigurationResponseView = appendLicenseDetails(tenantConfigurationResponseView, licenseDetails) } diff --git a/internal/commands/util/tenant_test.go b/internal/commands/util/tenant_test.go index 67b1a7271..1afac4eb3 100644 --- a/internal/commands/util/tenant_test.go +++ b/internal/commands/util/tenant_test.go @@ -8,41 +8,41 @@ import ( ) func TestTenantConfigurationHelp(t *testing.T) { - cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}, &mock.FeatureFlagsMockWrapper{}) + cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}) cmd.SetArgs([]string{"utils", "tenant", "--help"}) err := cmd.Execute() assert.Assert(t, err == nil) } func TestTenantConfigurationJsonFormat(t *testing.T) { - cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}, &mock.FeatureFlagsMockWrapper{}) + cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}) cmd.SetArgs([]string{"utils", "tenant", "--format", "json"}) err := cmd.Execute() assert.NilError(t, err, "Tenant configuration command should run with no errors and print to json") } func TestTenantConfigurationListFormat(t *testing.T) { - cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}, &mock.FeatureFlagsMockWrapper{}) + cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}) cmd.SetArgs([]string{"utils", "tenant", "--format", "list"}) err := cmd.Execute() assert.NilError(t, err, "Tenant configuration command should run with no errors and print to list") } func TestTenantConfigurationTableFormat(t *testing.T) { - cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}, &mock.FeatureFlagsMockWrapper{}) + cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}) cmd.SetArgs([]string{"utils", "tenant", "--format", "table"}) err := cmd.Execute() assert.NilError(t, err, "Tenant configuration command should run with no errors and print to table") } func TestTenantConfigurationInvalidFormat(t *testing.T) { - cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}, &mock.FeatureFlagsMockWrapper{}) + cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}) cmd.SetArgs([]string{"utils", "tenant", "--format", "MOCK"}) err := cmd.Execute() assert.Assert(t, err.Error() == mockFormatErrorMessage) } func TestNewTenantConfigurationCommand(t *testing.T) { - cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}, &mock.FeatureFlagsMockWrapper{}) + cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}) assert.Assert(t, cmd != nil, "Tenant configuration command must exist") } diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index 3b7285aa8..c16db6f93 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -77,7 +77,7 @@ func NewUtilsCommand( learnMoreCmd := NewLearnMoreCommand(learnMoreWrapper) - tenantCmd := NewTenantConfigurationCommand(tenantWrapper, jwtWrapper, featureFlagsWrapper) + tenantCmd := NewTenantConfigurationCommand(tenantWrapper, jwtWrapper) maskSecretsCmd := NewMaskSecretsCommand(chatWrapper) diff --git a/internal/params/envs.go b/internal/params/envs.go index 56f484b70..8af364ffe 100644 --- a/internal/params/envs.go +++ b/internal/params/envs.go @@ -81,6 +81,7 @@ const ( RiskManagementPathEnv = "CX_RISK_MANAGEMENT_PATH" ConfigFilePathEnv = "CX_CONFIG_FILE_PATH" RealtimeScannerPathEnv = "CX_REALTIME_SCANNER_PATH" + UniqueIDEnv = "CX_UNIQUE_ID" StartMultiPartUploadPathEnv = "CX_START_MULTIPART_UPLOAD_PATH" MultipartPresignedPathEnv = "CX_MULTIPART_PRESIGNED_URL_PATH" CompleteMultipartUploadPathEnv = "CX_COMPLETE_MULTIPART_UPLOAD_PATH" diff --git a/internal/params/flags.go b/internal/params/flags.go index 77b1807cf..c1165a96f 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -292,7 +292,7 @@ const ( APISecurityType = "api-security" AIProtectionType = "AI Protection" CheckmarxOneAssistType = "Checkmarx One Assist" - CheckmarxOneStandAloneType = "Standalone" + CheckmarxDevAssistType = "Checkmarx Developer Assist" ContainersType = "containers" APIDocumentationFlag = "apisec-swagger-filter" IacType = "iac-security" diff --git a/internal/params/keys.go b/internal/params/keys.go index bcab73654..841e656cf 100644 --- a/internal/params/keys.go +++ b/internal/params/keys.go @@ -80,6 +80,7 @@ var ( RiskManagementPathKey = strings.ToLower(RiskManagementPathEnv) ConfigFilePathKey = strings.ToLower(ConfigFilePathEnv) RealtimeScannerPathKey = strings.ToLower(RealtimeScannerPathEnv) + UniqueIDConfigKey = strings.ToLower(UniqueIDEnv) StartMultiPartUploadPathKey = strings.ToLower(StartMultiPartUploadPathEnv) MultipartPresignedPathKey = strings.ToLower(MultipartPresignedPathEnv) CompleteMultiPartUploadPathKey = strings.ToLower(CompleteMultipartUploadPathEnv) diff --git a/internal/services/realtimeengine/common.go b/internal/services/realtimeengine/common.go index 2b786746a..9537a1eb2 100644 --- a/internal/services/realtimeengine/common.go +++ b/internal/services/realtimeengine/common.go @@ -34,7 +34,12 @@ func EnsureLicense(jwtWrapper wrappers.JWTWrapper) error { return errors.Wrap(err, "failed to check AIProtectionType engine allowance") } - if aiAllowed || assistAllowed { + devAssistAllowed, err := jwtWrapper.IsAllowedEngine(params.CheckmarxDevAssistType) + if err != nil { + return errors.Wrap(err, "failed to check Checkmarx Developer Assist engine allowance") + } + + if aiAllowed || assistAllowed || devAssistAllowed { return nil } return errors.New(errorconstants.ErrMissingAIFeatureLicense) diff --git a/internal/wrappers/client.go b/internal/wrappers/client.go index 032eb4e4b..bf20407f2 100644 --- a/internal/wrappers/client.go +++ b/internal/wrappers/client.go @@ -126,12 +126,19 @@ func retryHTTPForIAMRequest(requestFunc func() (*http.Response, error), retries return nil, err } -func setAgentNameAndOrigin(req *http.Request) { +func setAgentNameAndOrigin(req *http.Request, isAuth bool) { agentStr := viper.GetString(commonParams.AgentNameKey) + "/" + commonParams.Version req.Header.Set("User-Agent", agentStr) originStr := viper.GetString(commonParams.OriginKey) req.Header.Set("Cx-Origin", originStr) + + if !isAuth { + uniqueID := GetUniqueID() + if uniqueID != "" { + req.Header.Set("UniqueId", uniqueID) + } + } } func GetClient(timeout uint) *http.Client { @@ -375,7 +382,7 @@ func SendHTTPRequestByFullURLContentLength( req.ContentLength = contentLength } client := GetClient(timeout) - setAgentNameAndOrigin(req) + setAgentNameAndOrigin(req, false) if auth { enrichWithOath2Credentials(req, accessToken, bearerFormat) } @@ -427,7 +434,7 @@ func SendHTTPRequestPasswordAuth(method string, body io.Reader, timeout uint, us } req, err := http.NewRequest(method, u, body) client := GetClient(timeout) - setAgentNameAndOrigin(req) + setAgentNameAndOrigin(req, true) if err != nil { return nil, err } @@ -464,7 +471,7 @@ func HTTPRequestWithQueryParams( } req, err := http.NewRequest(method, u, body) client := GetClient(timeout) - setAgentNameAndOrigin(req) + setAgentNameAndOrigin(req, false) if err != nil { return nil, err } @@ -512,7 +519,7 @@ func SendHTTPRequestWithJSONContentType(method, path string, body io.Reader, aut } req, err := http.NewRequest(method, fullURL, body) client := GetClient(timeout) - setAgentNameAndOrigin(req) + setAgentNameAndOrigin(req, false) req.Header.Add("Content-Type", jsonContentType) if err != nil { return nil, err @@ -645,7 +652,7 @@ func writeCredentialsToCache(accessToken string) { func getNewToken(credentialsPayload, authServerURI string) (string, error) { payload := strings.NewReader(credentialsPayload) req, err := http.NewRequest(http.MethodPost, authServerURI, payload) - setAgentNameAndOrigin(req) + setAgentNameAndOrigin(req, true) if err != nil { return "", err } diff --git a/internal/wrappers/client_test.go b/internal/wrappers/client_test.go index b8a45f0d1..e75e9e9b0 100644 --- a/internal/wrappers/client_test.go +++ b/internal/wrappers/client_test.go @@ -192,7 +192,7 @@ func TestSetAgentNameAndOrigin(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "http://example.com", nil) - setAgentNameAndOrigin(req) + setAgentNameAndOrigin(req, false) userAgent := req.Header.Get("User-Agent") origin := req.Header.Get("origin") diff --git a/internal/wrappers/jwt-helper.go b/internal/wrappers/jwt-helper.go index 7d7ab1669..25012ed28 100644 --- a/internal/wrappers/jwt-helper.go +++ b/internal/wrappers/jwt-helper.go @@ -1,13 +1,18 @@ package wrappers import ( + "os/user" "strconv" "strings" + "github.com/checkmarx/ast-cli/internal/logger" commonParams "github.com/checkmarx/ast-cli/internal/params" + "github.com/checkmarx/ast-cli/internal/wrappers/configuration" "github.com/checkmarx/ast-cli/internal/wrappers/utils" "github.com/golang-jwt/jwt/v5" + "github.com/google/uuid" "github.com/pkg/errors" + "github.com/spf13/viper" ) // JWTStruct model used to get all jwt fields @@ -24,7 +29,7 @@ type JWTStruct struct { type JWTWrapper interface { GetAllowedEngines(featureFlagsWrapper FeatureFlagsWrapper) (allowedEngines map[string]bool, err error) - GetLicenseDetails(featureFlagsWrapper FeatureFlagsWrapper) (licenseDetails map[string]string, err error) + GetLicenseDetails() (licenseDetails map[string]string, err error) IsAllowedEngine(engine string) (bool, error) ExtractTenantFromToken() (tenant string, err error) CheckPermissionByAccessToken(requiredPermission string) (permission bool, err error) @@ -78,7 +83,7 @@ func (*JWTStruct) GetAllowedEngines(featureFlagsWrapper FeatureFlagsWrapper) (al return getDefaultEngines(scsLicensingV2Flag.Status), nil } -func (*JWTStruct) GetLicenseDetails(featureFlagsWrapper FeatureFlagsWrapper) (licenseDetails map[string]string, err error) { +func (*JWTStruct) GetLicenseDetails() (licenseDetails map[string]string, err error) { licenseDetails = make(map[string]string) jwtStruct, err := getJwtStruct() @@ -86,22 +91,25 @@ func (*JWTStruct) GetLicenseDetails(featureFlagsWrapper FeatureFlagsWrapper) (li return nil, err } - assistEnabled := false - standaloneEnabled := false - for _, allowedEngine := range jwtStruct.AstLicense.LicenseData.AllowedEngines { - if strings.EqualFold(allowedEngine, commonParams.CheckmarxOneAssistType) || - strings.EqualFold(allowedEngine, commonParams.AIProtectionType) { - assistEnabled = true - } else if strings.EqualFold(allowedEngine, commonParams.CheckmarxOneStandAloneType) { - standaloneEnabled = true - } - } + assistEnabled := containsIgnoreCase(jwtStruct.AstLicense.LicenseData.AllowedEngines, commonParams.CheckmarxOneAssistType) || + containsIgnoreCase(jwtStruct.AstLicense.LicenseData.AllowedEngines, commonParams.AIProtectionType) + devAssistEnabled := containsIgnoreCase(jwtStruct.AstLicense.LicenseData.AllowedEngines, commonParams.CheckmarxDevAssistType) licenseDetails["scan.config.plugins.cxoneassist"] = strconv.FormatBool(assistEnabled) - licenseDetails["scan.config.plugins.standalone"] = strconv.FormatBool(standaloneEnabled) + licenseDetails["scan.config.plugins.cxdevassist"] = strconv.FormatBool(devAssistEnabled) return licenseDetails, nil } +// containsIgnoreCase returns true if target exists in arr using case-insensitive comparison +func containsIgnoreCase(arr []string, target string) bool { + for _, s := range arr { + if strings.EqualFold(s, target) { + return true + } + } + return false +} + func getJwtStruct() (*JWTStruct, error) { accessToken, err := GetAccessToken() if err != nil { @@ -184,3 +192,45 @@ func (*JWTStruct) CheckPermissionByAccessToken(requiredPermission string) (hasPe } return permission, nil } + +func GetUniqueID() string { + var uniqueID string + // Check License first + jwtWrapper := NewJwtWrapper() + isAllowed, err := jwtWrapper.IsAllowedEngine(commonParams.CheckmarxDevAssistType) + if err != nil { + logger.PrintIfVerbose("Failed to check engine allowance: " + err.Error()) + return "" + } + if !isAllowed { + logger.PrintIfVerbose("User does not have permission to standalone dev assists feature") + return "" + } + + // Check if unique id is already set + uniqueID = viper.GetString(commonParams.UniqueIDConfigKey) + if uniqueID != "" { + return uniqueID + } + + // Generate new unique id + currentUser, err := user.Current() + if err != nil { + logger.PrintIfVerbose("Failed to get user: " + err.Error()) + return "" + } + username := currentUser.Username + username = strings.TrimSpace(username) + if strings.Contains(username, "\\") { + username = strings.Split(username, "\\")[1] + } + uniqueID = uuid.New().String() + "_" + username + viper.Set(commonParams.UniqueIDConfigKey, uniqueID) + configFilePath, _ := configuration.GetConfigFilePath() + err = configuration.SafeWriteSingleConfigKeyString(configFilePath, commonParams.UniqueIDConfigKey, uniqueID) + if err != nil { + logger.PrintIfVerbose("Failed to write config: " + err.Error()) + return "" + } + return uniqueID +} diff --git a/internal/wrappers/jwt-helper_test.go b/internal/wrappers/jwt-helper_test.go index 8bf721983..ca51c1e19 100644 --- a/internal/wrappers/jwt-helper_test.go +++ b/internal/wrappers/jwt-helper_test.go @@ -1,8 +1,11 @@ package wrappers import ( + "strings" "testing" + commonParams "github.com/checkmarx/ast-cli/internal/params" + "github.com/spf13/viper" "gotest.tools/assert" ) @@ -71,3 +74,44 @@ func TestGetEnabledEngines(t *testing.T) { }) } } + +func TestGetUniqueID(t *testing.T) { + // Save original value and restore after test + originalID := viper.GetString(commonParams.UniqueIDConfigKey) + defer viper.Set(commonParams.UniqueIDConfigKey, originalID) + + t.Run("returns existing unique ID from config", func(t *testing.T) { + // Setup: set existing ID + existingID := "test-uuid-456_testuser" + viper.Set(commonParams.UniqueIDConfigKey, existingID) + + result := GetUniqueID() + + if result != "" { + assert.Equal(t, existingID, result) + } else { + t.Skip("Requires valid auth and 'Checkmarx Developer Assist' license") + } + }) + + t.Run("generates new unique ID when none exists", func(t *testing.T) { + // Setup: clear existing ID + viper.Set(commonParams.UniqueIDConfigKey, "") + + result := GetUniqueID() + + if result == "" { + t.Skip("Requires valid auth and 'Checkmarx Developer Assist' license") + return + } + + // Verify format: UUID_username + assert.Assert(t, strings.Contains(result, "_"), "Should have UUID_username format") + assert.Assert(t, len(result) > 36, "Should contain UUID and username") + + // Verify no backslash (Windows domain stripped) + parts := strings.Split(result, "_") + assert.Assert(t, len(parts) >= 2, "Should have at least 2 parts") + assert.Assert(t, !strings.Contains(parts[1], "\\"), "Username should not contain backslash") + }) +} diff --git a/internal/wrappers/mock/jwt-helper-mock.go b/internal/wrappers/mock/jwt-helper-mock.go index b71ef983e..eeb751aba 100644 --- a/internal/wrappers/mock/jwt-helper-mock.go +++ b/internal/wrappers/mock/jwt-helper-mock.go @@ -23,6 +23,8 @@ const SecretDetectionDisabled = 1 var engines = []string{"sast", "sca", "api-security", "iac-security", "scs", "containers", "enterprise-secrets"} +const licenseEnabledValue = "true" + // GetAllowedEngines mock for tests func (j *JWTMockWrapper) GetAllowedEngines(featureFlagsWrapper wrappers.FeatureFlagsWrapper) (allowedEngines map[string]bool, err error) { if j.CustomGetAllowedEngines != nil { @@ -77,17 +79,17 @@ func (j *JWTMockWrapper) CheckPermissionByAccessToken(requiredPermission string) return true, nil } -func (j *JWTMockWrapper) GetLicenseDetails(featureFlagsWrapper wrappers.FeatureFlagsWrapper) (licenseDetails map[string]string, err error) { +func (j *JWTMockWrapper) GetLicenseDetails() (licenseDetails map[string]string, err error) { licenseDetails = make(map[string]string) assistEnabled := (j.CheckmarxOneAssistEnabled != CheckmarxOneAssistDisabled) || (j.AIEnabled != AIProtectionDisabled) licenseDetails["scan.config.plugins.cxoneassist"] = strconv.FormatBool(assistEnabled) standaloneEnabled := true - licenseDetails["scan.config.plugins.standalone"] = strconv.FormatBool(standaloneEnabled) + licenseDetails["scan.config.plugins.cxdevassist"] = strconv.FormatBool(standaloneEnabled) for _, engine := range engines { - licenseDetails[engine] = "true" + licenseDetails[engine] = licenseEnabledValue } return licenseDetails, nil diff --git a/internal/wrappers/telemetry.go b/internal/wrappers/telemetry.go index 58e8a5b73..b3e58781f 100644 --- a/internal/wrappers/telemetry.go +++ b/internal/wrappers/telemetry.go @@ -10,6 +10,7 @@ type DataForAITelemetry struct { ScanType string `json:"scanType"` Status string `json:"status"` TotalCount int `json:"totalCount"` + UniqueID string `json:"uniqueId"` } type TelemetryWrapper interface {