mirror of https://github.com/vector-im/riot-web
Pass analyticsID to the elementCall iFrame (#9637)
Co-authored-by: Robin <robin@robin.town> Co-authored-by: Timo K <timok@element.io>pull/28217/head
parent
b81582d045
commit
ce75d3381f
|
@ -134,7 +134,7 @@ export class PosthogAnalytics {
|
|||
private readonly enabled: boolean = false;
|
||||
private static _instance = null;
|
||||
private platformSuperProperties = {};
|
||||
private static ANALYTICS_EVENT_TYPE = "im.vector.analytics";
|
||||
public static readonly ANALYTICS_EVENT_TYPE = "im.vector.analytics";
|
||||
private propertiesForNextEvent: Partial<Record<"$set" | "$set_once", UserProperties>> = {};
|
||||
private userPropertyCache: UserProperties = {};
|
||||
private authenticationType: Signup["authenticationType"] = "Other";
|
||||
|
|
|
@ -53,6 +53,7 @@ import { getCurrentLanguage } from "../languageHandler";
|
|||
import DesktopCapturerSourcePicker from "../components/views/elements/DesktopCapturerSourcePicker";
|
||||
import Modal from "../Modal";
|
||||
import { FontWatcher } from "../settings/watchers/FontWatcher";
|
||||
import { PosthogAnalytics } from "../PosthogAnalytics";
|
||||
|
||||
const TIMEOUT_MS = 16000;
|
||||
|
||||
|
@ -626,6 +627,15 @@ export class ElementCall extends Call {
|
|||
}
|
||||
|
||||
private constructor(public readonly groupCall: GroupCall, client: MatrixClient) {
|
||||
const accountAnalyticsData = client.getAccountData(PosthogAnalytics.ANALYTICS_EVENT_TYPE);
|
||||
// The analyticsID is passed directly to element call (EC) since this codepath is only for EC and no other widget.
|
||||
// We really don't want the same analyticID's for the EC and EW posthog instances (Data on posthog should be limited/anonymized as much as possible).
|
||||
// This is prohibited in EC where a hashed version of the analyticsID is used for the actual posthog identification.
|
||||
// We can pass the raw EW analyticsID here since we need to trust EC with not sending sensitive data to posthog (EC has access to more sensible data than the analyticsID e.g. the username)
|
||||
const analyticsID: string = accountAnalyticsData?.getContent().pseudonymousAnalyticsOptIn
|
||||
? accountAnalyticsData?.getContent().id
|
||||
: "";
|
||||
|
||||
// Splice together the Element Call URL for this call
|
||||
const params = new URLSearchParams({
|
||||
embed: "",
|
||||
|
@ -637,6 +647,7 @@ export class ElementCall extends Call {
|
|||
baseUrl: client.baseUrl,
|
||||
lang: getCurrentLanguage().replace("_", "-"),
|
||||
fontScale: `${SettingsStore.getValue("baseFontSize") / FontWatcher.DEFAULT_SIZE}`,
|
||||
analyticsID,
|
||||
});
|
||||
|
||||
// Set custom fonts
|
||||
|
|
|
@ -23,6 +23,7 @@ import { Room, RoomEvent } from "matrix-js-sdk/src/models/room";
|
|||
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
|
||||
import { Widget } from "matrix-widget-api";
|
||||
import { GroupCallIntent } from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import type { Mocked } from "jest-mock";
|
||||
import type { MatrixClient, IMyDevice } from "matrix-js-sdk/src/client";
|
||||
|
@ -40,6 +41,7 @@ import { ElementWidgetActions } from "../../src/stores/widgets/ElementWidgetActi
|
|||
import SettingsStore from "../../src/settings/SettingsStore";
|
||||
import Modal, { IHandle } from "../../src/Modal";
|
||||
import PlatformPeg from "../../src/PlatformPeg";
|
||||
import { PosthogAnalytics } from "../../src/PosthogAnalytics";
|
||||
|
||||
jest.spyOn(MediaDeviceHandler, "getDevices").mockResolvedValue({
|
||||
[MediaDeviceKindEnum.AudioInput]: [
|
||||
|
@ -622,6 +624,53 @@ describe("ElementCall", () => {
|
|||
|
||||
SettingsStore.getValue = originalGetValue;
|
||||
});
|
||||
|
||||
it("passes analyticsID through widget URL", async () => {
|
||||
client.getAccountData.mockImplementation((eventType: string) => {
|
||||
if (eventType === PosthogAnalytics.ANALYTICS_EVENT_TYPE) {
|
||||
return new MatrixEvent({ content: { id: "123456789987654321", pseudonymousAnalyticsOptIn: true } });
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
await ElementCall.create(room);
|
||||
const call = Call.get(room);
|
||||
if (!(call instanceof ElementCall)) throw new Error("Failed to create call");
|
||||
|
||||
const urlParams = new URLSearchParams(new URL(call.widget.url).hash.slice(1));
|
||||
expect(urlParams.get("analyticsID")).toBe("123456789987654321");
|
||||
});
|
||||
|
||||
it("does not pass analyticsID if `pseudonymousAnalyticsOptIn` set to false", async () => {
|
||||
client.getAccountData.mockImplementation((eventType: string) => {
|
||||
if (eventType === PosthogAnalytics.ANALYTICS_EVENT_TYPE) {
|
||||
return new MatrixEvent({
|
||||
content: { id: "123456789987654321", pseudonymousAnalyticsOptIn: false },
|
||||
});
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
await ElementCall.create(room);
|
||||
const call = Call.get(room);
|
||||
if (!(call instanceof ElementCall)) throw new Error("Failed to create call");
|
||||
|
||||
const urlParams = new URLSearchParams(new URL(call.widget.url).hash.slice(1));
|
||||
expect(urlParams.get("analyticsID")).toBe("");
|
||||
});
|
||||
|
||||
it("passes empty analyticsID if the id is not in the account data", async () => {
|
||||
client.getAccountData.mockImplementation((eventType: string) => {
|
||||
if (eventType === PosthogAnalytics.ANALYTICS_EVENT_TYPE) {
|
||||
return new MatrixEvent({ content: {} });
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
await ElementCall.create(room);
|
||||
const call = Call.get(room);
|
||||
if (!(call instanceof ElementCall)) throw new Error("Failed to create call");
|
||||
|
||||
const urlParams = new URLSearchParams(new URL(call.widget.url).hash.slice(1));
|
||||
expect(urlParams.get("analyticsID")).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("instance in a non-video room", () => {
|
||||
|
|
|
@ -136,7 +136,7 @@ export function createTestClient(): MatrixClient {
|
|||
getTurnServers: jest.fn().mockReturnValue([]),
|
||||
getTurnServersExpiry: jest.fn().mockReturnValue(2 ^ 32),
|
||||
getThirdpartyUser: jest.fn().mockResolvedValue([]),
|
||||
getAccountData: (type) => {
|
||||
getAccountData: jest.fn().mockImplementation((type) => {
|
||||
return mkEvent({
|
||||
user: undefined,
|
||||
room: undefined,
|
||||
|
@ -144,7 +144,7 @@ export function createTestClient(): MatrixClient {
|
|||
event: true,
|
||||
content: {},
|
||||
});
|
||||
},
|
||||
}),
|
||||
mxcUrlToHttp: (mxc) => `http://this.is.a.url/${mxc.substring(6)}`,
|
||||
setAccountData: jest.fn(),
|
||||
setRoomAccountData: jest.fn(),
|
||||
|
|
Loading…
Reference in New Issue