Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions client/lib/atomic-wallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
getAtomicWalletGiftCardLink,
normalizeGiftCardProvider,
getGiftCardProviderFromSubscription,
stripTrackingParams,
} from "./atomic-wallet"

describe("Atomic Wallet gift card deep links", () => {
Expand Down Expand Up @@ -44,3 +45,39 @@ describe("Atomic Wallet gift card deep links", () => {
)
})
})

describe("stripTrackingParams", () => {
it("strips UTM parameters from URLs", () => {
const url = "https://example.com/page?amount=25&utm_source=app&utm_medium=referral&utm_campaign=test"
const stripped = stripTrackingParams(url)
expect(stripped).toBe("https://example.com/page?amount=25")
})

it("strips fbclid and gclid parameters", () => {
const url = "https://example.com/?item=1&fbclid=abc123&gclid=def456"
const stripped = stripTrackingParams(url)
expect(stripped).toBe("https://example.com/?item=1")
})

it("strips ref and source parameters", () => {
const url = "https://example.com/?amount=10&ref=syncro&source=app"
const stripped = stripTrackingParams(url)
expect(stripped).toBe("https://example.com/?amount=10")
})

it("preserves non-tracking parameters", () => {
const url = "https://example.com/buy?amount=25&provider=amazon"
const stripped = stripTrackingParams(url)
expect(stripped).toBe("https://example.com/buy?amount=25&provider=amazon")
})

it("returns original string for non-URL inputs", () => {
const url = "not-a-url"
expect(stripTrackingParams(url)).toBe("not-a-url")
})

it("handles URLs with no query params", () => {
const url = "https://example.com/page"
expect(stripTrackingParams(url)).toBe("https://example.com/page")
})
})
31 changes: 28 additions & 3 deletions client/lib/atomic-wallet.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export const ATOMIC_WALLET_MOBILE_SCHEME = "atomicwallet://buy-gift-card"
export const ATOMIC_WALLET_WEB_URL = "https://atomicwallet.io/buy-gift-cards"

const TRACKING_PARAM_PREFIXES = ["utm_", "fbclid", "gclid", "ref", "source", "campaign", "medium", "content", "term"]

const GIFT_CARD_PROVIDER_ALIASES: Array<[RegExp, string]> = [
[/amazon/i, "amazon"],
[/google\s*play|youtube|google play/i, "google_play"],
Expand All @@ -14,6 +16,25 @@ const SUPPORTED_GIFT_CARD_PROVIDERS = new Set(
GIFT_CARD_PROVIDER_ALIASES.map(([, provider]) => provider),
)

export function stripTrackingParams(url: string): string {
try {
const parsed = new URL(url)
const keysToRemove: string[] = []
parsed.searchParams.forEach((_, key) => {
const lower = key.toLowerCase()
if (TRACKING_PARAM_PREFIXES.some((prefix) => lower.startsWith(prefix))) {
keysToRemove.push(key)
}
})
for (const key of keysToRemove) {
parsed.searchParams.delete(key)
}
return parsed.toString()
} catch {
return url
}
}

export function normalizeGiftCardProvider(provider: string): string {
return provider.trim().replace(/\s+/g, "_").toLowerCase()
}
Expand All @@ -33,14 +54,18 @@ export function getAtomicWalletGiftCardDeepLink(amount: number, provider: string
const normalizedProvider = normalizeGiftCardProvider(provider)
const encodedProvider = encodeURIComponent(normalizedProvider)
const encodedAmount = encodeURIComponent(amount.toString())
return `${ATOMIC_WALLET_MOBILE_SCHEME}?amount=${encodedAmount}&provider=${encodedProvider}`
return stripTrackingParams(
`${ATOMIC_WALLET_MOBILE_SCHEME}?amount=${encodedAmount}&provider=${encodedProvider}`
)
}

export function getAtomicWalletGiftCardWebLink(amount: number, provider: string): string {
const normalizedProvider = normalizeGiftCardProvider(provider)
const encodedProvider = encodeURIComponent(normalizedProvider)
const encodedAmount = encodeURIComponent(amount.toString())
return `${ATOMIC_WALLET_WEB_URL}?amount=${encodedAmount}&provider=${encodedProvider}`
return stripTrackingParams(
`${ATOMIC_WALLET_WEB_URL}?amount=${encodedAmount}&provider=${encodedProvider}`
)
}

export function getAtomicWalletGiftCardLink(amount: number, provider: string): string {
Expand All @@ -59,7 +84,7 @@ export function openAtomicWalletGiftCard(amount: number, provider: string): stri
const url = getAtomicWalletGiftCardLink(amount, provider)

if (typeof window !== "undefined") {
window.location.href = url
window.open(url, "_blank", "noreferrer,noopener")
}

return url
Expand Down
9 changes: 9 additions & 0 deletions client/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ const nextConfig = {
},
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'Referrer-Policy',
value: 'no-referrer',
},
],
},
{
source: '/sw.js',
headers: [
Expand Down
Loading