Skip to content

Commit

Permalink
Set Sentry user id to hashed identifier
Browse files Browse the repository at this point in the history
We calculate the ID of the user by hashing the address. This way we won't
store any sensitive information in Sentry.
  • Loading branch information
nkuba committed Nov 27, 2024
1 parent 254e90b commit eb17ace
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 1 deletion.
2 changes: 2 additions & 0 deletions dapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@tanstack/react-query-devtools": "^5.49.2",
"axios": "^1.6.7",
"bignumber.js": "^9.1.2",
"crypto-js": "^4.2.0",
"ethers": "^6.10.0",
"formik": "^2.4.5",
"framer-motion": "^10.16.5",
Expand All @@ -52,6 +53,7 @@
"devDependencies": {
"@sentry/vite-plugin": "^2.22.5",
"@thesis-co/eslint-config": "github:thesis/eslint-config#7b9bc8c",
"@types/crypto-js": "^4.2.2",
"@types/luxon": "^3.4.2",
"@types/react": "^18.2.38",
"@types/react-dom": "^18.2.17",
Expand Down
38 changes: 38 additions & 0 deletions dapp/src/sentry.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { describe, expect, it, vi } from "vitest"
import * as Sentry from "@sentry/react"
import sentry from "./sentry"

describe("sentry", () => {
describe("setUser", () => {
vi.mock("@sentry/react")

const testCases = [
{ bitcoinAddress: undefined, expectedResult: null },
{ bitcoinAddress: "", expectedResult: null },
{ bitcoinAddress: " ", expectedResult: null },
{
bitcoinAddress: "17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem",
expectedResult: { id: "1f520a9757" },
},
{
bitcoinAddress: "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4",
expectedResult: { id: "6cd42dab02" },
},
{
bitcoinAddress: "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4",
expectedResult: { id: "6cd42dab02" },
},
]

describe.each(testCases)(
"when address is $bitcoinAddress",
({ bitcoinAddress, expectedResult }) => {
it("should set expected user in Sentry", () => {
sentry.setUser(bitcoinAddress)

expect(Sentry.setUser).toHaveBeenCalledWith(expectedResult)
})
},
)
})
})
23 changes: 22 additions & 1 deletion dapp/src/sentry/index.ts → dapp/src/sentry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as Sentry from "@sentry/react"
import * as CryptoJS from "crypto-js"

const initialize = (dsn: string) => {
Sentry.init({
Expand All @@ -17,8 +18,28 @@ const initialize = (dsn: string) => {
})
}

/**
* Sets the user in Sentry with an ID from hashed Bitcoin address.
* The Bitcoin address is first converted to lowercase and then hashed using SHA-256.
* The resulting hash is then converted to a hexadecimal string and the first 10
* characters are set as the user ID.
*
* @param bitcoinAddress - The Bitcoin address of the user. If undefined, the user
* is set to null in Sentry.
*/
const setUser = (bitcoinAddress: string | undefined) => {
Sentry.setUser(bitcoinAddress ? { id: bitcoinAddress } : null)
if (!bitcoinAddress) {
Sentry.setUser(null)
return
}

const hashedBitcoinAddress = CryptoJS.SHA256(
bitcoinAddress.toLowerCase(),
).toString(CryptoJS.enc.Hex)

const id = hashedBitcoinAddress.slice(0, 10)

Sentry.setUser({ id })
}

const captureException = (exception: unknown) =>
Expand Down

0 comments on commit eb17ace

Please sign in to comment.