From 3739d7752d174dd5b05ad50c0d9e181629c16b5a Mon Sep 17 00:00:00 2001 From: vklimontovich Date: Fri, 7 May 2021 20:05:33 +0300 Subject: [PATCH 1/2] Telemetry enhancements (mainly, data masking improvements) - data masking is moved to a separate function; - hostnames and urls are masked now - collect pageview for pages not wrapped in Shell --- components/Shell.tsx | 4 ++-- lib/telemetry.ts | 37 ++++++++++++++++++++++++++++++++++++- pages/[user]/book.tsx | 6 +++--- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/components/Shell.tsx b/components/Shell.tsx index 3810f5d5..b3b861f7 100644 --- a/components/Shell.tsx +++ b/components/Shell.tsx @@ -3,7 +3,7 @@ import {useContext, useEffect, useState} from "react"; import { useRouter } from "next/router"; import { signOut, useSession } from 'next-auth/client'; import { MenuIcon, XIcon } from '@heroicons/react/outline'; -import {TelemetryContext, useTelemetry} from "../lib/telemetry"; +import {collectPageParameters, telemetryEventTypes, useTelemetry} from "../lib/telemetry"; export default function Shell(props) { const router = useRouter(); @@ -14,7 +14,7 @@ export default function Shell(props) { useEffect(() => { telemetry.withJitsu((jitsu) => { - return jitsu.track('page_view', {page_url: router.pathname, page_title: "", source_ip: ""}) + return jitsu.track(telemetryEventTypes.pageView, collectPageParameters(router.pathname)) }); }, [telemetry]) diff --git a/lib/telemetry.ts b/lib/telemetry.ts index 5cc38163..c1047c9e 100644 --- a/lib/telemetry.ts +++ b/lib/telemetry.ts @@ -1,6 +1,16 @@ import React, {useContext} from 'react' import {jitsuClient, JitsuClient} from "@jitsu/sdk-js"; +/** + * Enumeration of all event types that are being sent + * to telemetry collection. + */ +export const telemetryEventTypes = { + pageView: 'page_view', + dateSelected: 'date_selected', + timeSelected: 'time_selected', + bookingConfirmed: 'booking_confirmed' +} /** * Telemetry client @@ -21,6 +31,31 @@ function useTelemetry(): TelemetryClient { return useContext(TelemetryContext); } +function isLocalhost(host: string) { + return "localhost" === host || "127.0.0.1" === host; +} + +/** + * Collects page parameters and makes sure no sensitive data made it to telemetry + * @param route current next.js route + */ +export function collectPageParameters(route?: string): any { + let host = document.location.hostname; + let maskedHost = isLocalhost(host) ? "localhost" : "masked"; + //starts with '' + let docPath = route ?? ""; + return { + page_url: route, + page_title: "", + source_ip: "", + url: document.location.protocol + "//" + host + (docPath ?? ""), + doc_host: maskedHost, + doc_search: "", + doc_path: docPath, + referer: "", + } +} + function createTelemetryClient(): TelemetryClient { if (process.env.NEXT_PUBLIC_TELEMETRY_KEY) { return { @@ -36,7 +71,7 @@ function createTelemetryClient(): TelemetryClient { window['jitsu'] = jitsuClient({ log_level: 'ERROR', tracking_host: "https://t.calendso.com", - key: "js.2pvs2bbpqq1zxna97wcml.oi2jzirnbj1ev4tc57c5r", + key: process.env.NEXT_PUBLIC_TELEMETRY_KEY, cookie_name: "__clnds", capture_3rd_party_cookies: false, }); diff --git a/pages/[user]/book.tsx b/pages/[user]/book.tsx index 9e270b84..ce56b0f6 100644 --- a/pages/[user]/book.tsx +++ b/pages/[user]/book.tsx @@ -3,7 +3,7 @@ import Link from 'next/link'; import { useRouter } from 'next/router'; import { ClockIcon, CalendarIcon } from '@heroicons/react/solid'; import prisma from '../../lib/prisma'; -import {useTelemetry} from "../../lib/telemetry"; +import {collectPageParameters, telemetryEventTypes, useTelemetry} from "../../lib/telemetry"; import {useEffect} from "react"; const dayjs = require('dayjs'); @@ -12,12 +12,12 @@ export default function Book(props) { const { date, user } = router.query; const telemetry = useTelemetry(); useEffect(() => { - telemetry.withJitsu(jitsu => jitsu.track('time_selected', { page_title: "", source_ip: "" })); + telemetry.withJitsu(jitsu => jitsu.track(telemetryEventTypes.timeSelected, collectPageParameters())); }) const bookingHandler = event => { event.preventDefault(); - telemetry.withJitsu(jitsu => jitsu.track('booking_confirmed', { page_title: "", source_ip: "" })); + telemetry.withJitsu(jitsu => jitsu.track(telemetryEventTypes.bookingConfirmed, collectPageParameters())); const res = fetch( '/api/book/' + user, { From db05c587a3a68a8361580051ee04a127161072b1 Mon Sep 17 00:00:00 2001 From: vklimontovich Date: Fri, 7 May 2021 20:07:36 +0300 Subject: [PATCH 2/2] collect pageview for pages not wrapped in Shell --- pages/[user]/[type].tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index 3e5a201d..4c3401db 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -17,7 +17,7 @@ dayjs.extend(utc); dayjs.extend(timezone); import getSlots from '../../lib/slots'; -import {useTelemetry} from "../../lib/telemetry"; +import {collectPageParameters, telemetryEventTypes, useTelemetry} from "../../lib/telemetry"; function classNames(...classes) { return classes.filter(Boolean).join(' ') @@ -34,7 +34,7 @@ export default function Type(props) { const telemetry = useTelemetry(); const [selectedTimeZone, setSelectedTimeZone] = useState(''); - + function toggleTimeOptions() { setIsTimeOptionsOpen(!isTimeOptionsOpen); } @@ -44,6 +44,10 @@ export default function Type(props) { setSelectedTimeZone(dayjs.tz.guess()) }, []) + useEffect(() => { + telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.pageView, collectPageParameters())) + }) + // Get router variables const router = useRouter(); @@ -91,7 +95,7 @@ export default function Type(props) { // Combine placeholder days with actual days const calendar = [...emptyDays, ...days.map((day) => - {isTimeOptionsOpen && + {isTimeOptionsOpen &&
Time Options