In this article, we will review telemetry.ts file in Flyde codebase. We will look at:
- reportEvent(). 
- sanitizeProperties(). 
- isSafeProperty(). 
- sanitizeValue(). 
reportEvent()
reportEvent function is exported in telemetry.ts file as shown below:
export function reportEvent(
  distinctId: string,
  event: string,
  properties?: Record<string, any>
): void {
  // Check if telemetry is disabled via environment variable
  if (typeof process !== 'undefined' && process.env?.FLYDE_TELEMETRY_DISABLED === 'true') {
    return;
  }
  // Disable in CI/CD and production environments
  if (typeof process !== 'undefined' && process.env) {
    const env = process.env;
    // Disable in CI
    if (env.CI === 'true') {
      return;
    }
    // Disable in production
    if (env.NODE_ENV === 'production') {
      return;
    }
  }
  // Fire and forget
  (async () => {
    try {
      const sanitizedProperties = sanitizeProperties(properties);
      const payload: TelemetryEvent = {
        distinctId,
        event,
        properties: {
          ...sanitizedProperties,
          flydeVersion: FLYDE_VERSION
        }
      };
      fetch(TELEMETRY_ENDPOINT, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(payload)
      });
    } catch (error) {
      // Silently fail - telemetry should not break the app
    }
  })();
}
This code snippet is self explanatory with helpful comments. What I find interesting is that “fire and forget” type of invocation. This is an IIFE.
Also notice that catch block is empty.
sanitizeProperties()
sanitizeProperties is defined as shown below:
function sanitizeProperties(properties?: Record<string, any>): Record<string, any> {
  if (!properties) {
    return {};
  }
  const sanitized: Record<string, any> = {};
  for (const [key, value] of Object.entries(properties)) {
    if (isSafeProperty(key, value)) {
      sanitized[key] = sanitizeValue(value);
    }
  }
  return sanitized;
}
This function iterates over the object keys and checks if it is a safe property and then sanitizes value.
Two questions come to mind.
- What does safe here mean? 
- What does sanitize value here mean? 
Continue reading.
isSafeProperty()
isSafeProperty function is defined as shown below:
function isSafeProperty(key: string, _value: any): boolean {
  const sensitiveKeys = [
    'token', 'password', 'secret', 'key', 'auth', 'credential',
    'email', 'username', 'path', 'file', 'content', 'code'
  ];
  const lowerKey = key.toLowerCase();
  if (sensitiveKeys.some(sensitive => lowerKey.includes(sensitive))) {
    return false;
  }
  return true;
}
Interesting usage of “some” here and this is based on sensitiveKeys array.
sanitizeValue()
sanitizeValue is defined as shown below:
function sanitizeValue(value: any): any {
  if (typeof value === 'string' && value.length > 100) {
    return '[Redacted]';
  }
  if (typeof value === 'object' && value !== null) {
    return '[Object]';
  }
  return value;
}
sanitize here means sensitive info gets redacted and if the value is of type object, it returns [Object].
About me:
Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.
Email: ramu.narasinga@gmail.com
Want to learn from open-source? Solve challenges inspired by open-source projects.
 


 
    
Top comments (0)