Skip to content

Commit 7b033ad

Browse files
gagiknirinchev
andauthored
chore: switch to @mongodb-js/device-id (#196)
Co-authored-by: Nikola Irinchev <[email protected]>
1 parent e200559 commit 7b033ad

File tree

7 files changed

+30
-168
lines changed

7 files changed

+30
-168
lines changed

eslint.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export default defineConfig([
4848
"coverage",
4949
"global.d.ts",
5050
"eslint.config.js",
51-
"jest.config.ts",
51+
"jest.config.cjs",
5252
"src/types/*.d.ts",
5353
]),
5454
eslintPluginPrettierRecommended,

jest.config.ts renamed to jest.config.cjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/** @type {import('ts-jest').JestConfigWithTsJest} **/
2-
export default {
2+
module.exports = {
33
preset: "ts-jest/presets/default-esm",
44
testEnvironment: "node",
55
extensionsToTreatAsEsm: [".ts"],

package-lock.json

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
},
6262
"dependencies": {
6363
"@modelcontextprotocol/sdk": "^1.8.0",
64+
"@mongodb-js/device-id": "^0.2.1",
6465
"@mongodb-js/devtools-connect": "^3.7.2",
6566
"@mongosh/service-provider-node-driver": "^3.6.0",
6667
"bson": "^6.10.3",

src/helpers/deferred-promise.ts

-58
This file was deleted.

src/telemetry/telemetry.ts

+20-36
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ import logger, { LogId } from "../logger.js";
55
import { ApiClient } from "../common/atlas/apiClient.js";
66
import { MACHINE_METADATA } from "./constants.js";
77
import { EventCache } from "./eventCache.js";
8-
import { createHmac } from "crypto";
98
import nodeMachineId from "node-machine-id";
10-
import { DeferredPromise } from "../helpers/deferred-promise.js";
9+
import { getDeviceId } from "@mongodb-js/device-id";
1110

1211
type EventResult = {
1312
success: boolean;
@@ -19,7 +18,8 @@ export const DEVICE_ID_TIMEOUT = 3000;
1918
export class Telemetry {
2019
private isBufferingEvents: boolean = true;
2120
/** Resolves when the device ID is retrieved or timeout occurs */
22-
public deviceIdPromise: DeferredPromise<string> | undefined;
21+
public deviceIdPromise: Promise<string> | undefined;
22+
private deviceIdAbortController = new AbortController();
2323
private eventCache: EventCache;
2424
private getRawMachineId: () => Promise<string>;
2525

@@ -39,7 +39,6 @@ export class Telemetry {
3939
{
4040
commonProperties = { ...MACHINE_METADATA },
4141
eventCache = EventCache.getInstance(),
42-
4342
getRawMachineId = () => nodeMachineId.machineId(true),
4443
}: {
4544
eventCache?: EventCache;
@@ -57,50 +56,35 @@ export class Telemetry {
5756
if (!this.isTelemetryEnabled()) {
5857
return;
5958
}
60-
this.deviceIdPromise = DeferredPromise.fromPromise(this.getDeviceId(), {
61-
timeout: DEVICE_ID_TIMEOUT,
62-
onTimeout: (resolve) => {
63-
resolve("unknown");
64-
logger.debug(LogId.telemetryDeviceIdTimeout, "telemetry", "Device ID retrieval timed out");
59+
this.deviceIdPromise = getDeviceId({
60+
getMachineId: () => this.getRawMachineId(),
61+
onError: (reason, error) => {
62+
switch (reason) {
63+
case "resolutionError":
64+
logger.debug(LogId.telemetryDeviceIdFailure, "telemetry", String(error));
65+
break;
66+
case "timeout":
67+
logger.debug(LogId.telemetryDeviceIdTimeout, "telemetry", "Device ID retrieval timed out");
68+
break;
69+
case "abort":
70+
// No need to log in the case of aborts
71+
break;
72+
}
6573
},
74+
abortSignal: this.deviceIdAbortController.signal,
6675
});
76+
6777
this.commonProperties.device_id = await this.deviceIdPromise;
6878

6979
this.isBufferingEvents = false;
7080
}
7181

7282
public async close(): Promise<void> {
73-
this.deviceIdPromise?.resolve("unknown");
83+
this.deviceIdAbortController.abort();
7484
this.isBufferingEvents = false;
7585
await this.emitEvents(this.eventCache.getEvents());
7686
}
7787

78-
/**
79-
* @returns A hashed, unique identifier for the running device or `"unknown"` if not known.
80-
*/
81-
private async getDeviceId(): Promise<string> {
82-
try {
83-
if (this.commonProperties.device_id) {
84-
return this.commonProperties.device_id;
85-
}
86-
87-
const originalId: string = await this.getRawMachineId();
88-
89-
// Create a hashed format from the all uppercase version of the machine ID
90-
// to match it exactly with the denisbrodbeck/machineid library that Atlas CLI uses.
91-
const hmac = createHmac("sha256", originalId.toUpperCase());
92-
93-
/** This matches the message used to create the hashes in Atlas CLI */
94-
const DEVICE_ID_HASH_MESSAGE = "atlascli";
95-
96-
hmac.update(DEVICE_ID_HASH_MESSAGE);
97-
return hmac.digest("hex");
98-
} catch (error) {
99-
logger.debug(LogId.telemetryDeviceIdFailure, "telemetry", String(error));
100-
return "unknown";
101-
}
102-
}
103-
10488
/**
10589
* Emits events through the telemetry pipeline
10690
* @param events - The events to emit

tests/unit/deferred-promise.test.ts

-72
This file was deleted.

0 commit comments

Comments
 (0)