Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions packages/cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,18 @@ var loginCmd = &cobra.Command{
util.HandleError(err, "Unable to write write to Infisical Config file. Please try again")
}

// Identify the user in PostHog and alias the anonymous machine ID
// so that pre-login CLI events are merged into the same person record
Telemetry.IdentifyUser(userCredentialsToBeStored.Email)

// clear backed up secrets from prev account
util.DeleteBackupSecrets()

// Capture login event and flush the PostHog client (including Identify/Alias
// events enqueued by IdentifyUser above). This must run before any early
// returns so that all enqueued events are flushed via CaptureEvent's Close().
Telemetry.CaptureEvent("cli-command:login", posthog.NewProperties().Set("infisical-backend", config.INFISICAL_URL).Set("version", util.CLI_VERSION))

if plainOutput {
util.PrintlnStdout(userCredentialsToBeStored.JTWToken)
return
Expand All @@ -260,8 +269,6 @@ var loginCmd = &cobra.Command{
plainBold.Println("\nQuick links")
util.PrintlnStderr("- Learn to inject secrets into your application at https://infisical.com/docs/cli/usage")
util.PrintlnStderr("- Stuck? Join our slack for quick support https://infisical.com/slack")

Telemetry.CaptureEvent("cli-command:login", posthog.NewProperties().Set("infisical-backend", config.INFISICAL_URL).Set("version", util.CLI_VERSION))
} else {
sdkAuthenticator := util.NewSdkAuthenticator(infisicalClient, cmd)

Expand Down
49 changes: 43 additions & 6 deletions packages/telemetry/telemetry.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package telemetry

import (
"errors"

"github.com/Infisical/infisical-merge/packages/util"
"github.com/denisbrodbeck/machineid"
"github.com/posthog/posthog-go"
Expand Down Expand Up @@ -56,27 +58,62 @@ func (t *Telemetry) CaptureEvent(eventName string, properties posthog.Properties
}
}

// IdentifyUser sends a PostHog identify call to enrich the person record
// with user properties, and aliases the anonymous machine ID to the user's
// email so that pre-login CLI events are merged into the same person.
func (t *Telemetry) IdentifyUser(email string) {
if !t.isEnabled || email == "" {
return
}

// Identify the user with their email as the distinctId
t.posthogClient.Enqueue(posthog.Identify{
DistinctId: email,
Properties: posthog.NewProperties().
Set("email", email),
})

// Alias the anonymous machine ID to the user's email so that
// any events captured before login are linked to this person
machineId, err := machineid.ID()
if err == nil && machineId != "" {
anonymousId := "anonymous_cli_" + machineId
t.posthogClient.Enqueue(posthog.Alias{
DistinctId: email,
Alias: anonymousId,
})
}

// Note: no Close() here — the caller is responsible for ensuring
// CaptureEvent (which calls Close) runs after IdentifyUser to flush
// all enqueued events (Identify, Alias, and Capture).
}

func (t *Telemetry) GetDistinctId() (string, error) {
var distinctId string
var outputErr error

machineId, err := machineid.ID()
if err != nil {
outputErr = err
log.Debug().Err(err).Msg("failed to get machine ID for telemetry")
}

infisicalConfig, err := util.GetConfigFile()
if err != nil {
outputErr = err
log.Debug().Err(err).Msg("failed to get config file for telemetry")
}

if infisicalConfig.LoggedInUserEmail != "" {
distinctId = infisicalConfig.LoggedInUserEmail
} else if machineId != "" {
distinctId = "anonymous_cli_" + machineId
} else {
distinctId = ""
}

return distinctId, outputErr
// Only return an error if we could not resolve any distinctId.
// Non-critical errors (e.g. machineid failure when email is available)
// are logged above but should not prevent event capture.
if distinctId == "" {
return "", errors.New("unable to resolve a distinct ID for telemetry")
}

return distinctId, nil
}
Loading