Skip to content

Commit

Permalink
feat(telemetry): salt id’s
Browse files Browse the repository at this point in the history
  • Loading branch information
tknickman committed Dec 11, 2023
1 parent caacef4 commit c5b8ddc
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 5 deletions.
6 changes: 4 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/turborepo-telemetry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ chrono = { workspace = true, features = ["serde"] }
config = "0.13.4"
dirs-next = "2.0.0"
futures = { workspace = true }
hex = "0.4.3"
once_cell = "1.18.0"
reqwest = { workspace = true, features = ["json"] }
rustc_version_runtime = "0.3.0"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = "0.10.8"
thiserror = { workspace = true }
tokio = { workspace = true, features = ["full", "time"] }
tracing = { workspace = true }
Expand Down
29 changes: 27 additions & 2 deletions crates/turborepo-telemetry/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ use std::{env, fs, path::Path};

use chrono::{DateTime, Utc};
pub use config::{Config, ConfigError, File, FileFormat};
use hex;
use serde::{Deserialize, Serialize};
use serde_json;
use sha2::{Digest, Sha256};
use tracing::{debug, error};
use turborepo_ui::{BOLD, GREY, UI, UNDERLINE};
use uuid::Uuid;
Expand All @@ -12,21 +14,40 @@ static DEBUG_ENV_VAR: &str = "TURBO_TELEMETRY_DEBUG";
static DISABLED_ENV_VAR: &str = "TURBO_TELEMETRY_DISABLED";
static DO_NOT_TRACK_ENV_VAR: &str = "DO_NOT_TRACK";

fn salt_string(salt: &str, input: &str) -> String {
let salted = format!("{}{}", salt, input);
let mut hasher = Sha256::new();
hasher.update(salted.as_bytes());
let generic = hasher.finalize();
hex::encode(generic)
}

#[derive(Debug, Deserialize, Serialize)]
pub struct TelemetryConfigContents {
telemetry_id: String,
// whether or not telemetry is enabled
telemetry_enabled: bool,
// randomized and salted machine id - used for linking events together
telemetry_id: String,
// private salt used to anonymize event data (telemetry_id, task names, package names, etc.) -
// this is generated on first run and never leaves the machine
telemetry_salt: String,

// when the alert was shown
#[serde(skip_serializing_if = "Option::is_none")]
telemetry_alerted: Option<DateTime<Utc>>,
}

impl Default for TelemetryConfigContents {
fn default() -> Self {
let telemetry_salt = Uuid::new_v4().to_string();
let raw_telemetry_id = Uuid::new_v4().to_string();
let telemetry_id = salt_string(&telemetry_salt, &raw_telemetry_id);

TelemetryConfigContents {
telemetry_id: Uuid::new_v4().to_string(),
telemetry_enabled: true,
telemetry_alerted: None,
telemetry_salt,
telemetry_id,
}
}
}
Expand Down Expand Up @@ -108,6 +129,10 @@ impl TelemetryConfig {
Ok(())
}

pub fn salt(&self, input: &str) -> String {
salt_string(&self.config.telemetry_salt, input)
}

pub fn show_alert(&mut self) {
if !self.has_seen_alert() && self.is_enabled() {
println!(
Expand Down
7 changes: 6 additions & 1 deletion crates/turborepo-telemetry/src/telemetry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ impl TelemetryClient for AnonAPIClient {
session_id: &str,
) -> Result<(), Error> {
let request_builder = self
.create_request_builder("/api/turborepo/v1", Method::POST, session_id, telemetry_id)
.create_request_builder(
"/api/turborepo/v1/events",
Method::POST,
session_id,
telemetry_id,
)
.await?
.json(&events);

Expand Down

0 comments on commit c5b8ddc

Please sign in to comment.