feat(privacy): strip tracking parameters from links on paste, send and render (#103)
Shared links routinely carry ad/analytics identifiers (utm_*, fbclid, gclid, YouTube si=, Amazon ref=/tag=, X s=/t=, TikTok _r/_t, …) that tie every recipient's click back to the person who shared the link. New src/app/utils/urlTracking.ts is a pure, local stripper: a global list + utm_/pk_/matomo_ prefixes, plus host-scoped rules so e.g. `si` is only removed on youtube/spotify. matrix.to and non-http(s) schemes are never rewritten; unparseable input is returned unchanged; Amazon's `th`/`psc` variant selectors are deliberately kept. 13 unit tests. Wired at three points, all behind a new Settings → Privacy toggle (`stripTrackingParams`, default on): - paste: plain-text pastes are cleaned and re-inserted through Slate's own insertData so multi-line pastes still split into paragraphs; - send: RoomInput submit + schedule paths and MessageEditor saves clean both `body` and `formatted_body` (the HTML variant unescapes `&` around each URL and re-escapes it so the markup is untouched); - render: linkify `formatHref`/`format` and explicit `<a href>` in formatted_body are cleaned, so links sent from other clients are safe to click too. LINKIFY_OPTS is spread into memoised per-timeline objects, so the toggle is a module flag kept current by ClientNonUIFeatures. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -20,6 +20,7 @@ import { notificationPermission, setFavicon, showOsNotification } from '../../ut
|
||||
import { NOTIFICATION_SOUND_MAP } from '../../utils/notificationSounds';
|
||||
import { useSetting } from '../../state/hooks/settings';
|
||||
import { settingsAtom } from '../../state/settings';
|
||||
import { setStripTrackingOnRender } from '../../plugins/react-custom-html-parser';
|
||||
import { allInvitesAtom } from '../../state/room-list/inviteList';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { useHydrateMsgDrafts } from '../../hooks/useHydrateMsgDrafts';
|
||||
@@ -90,6 +91,11 @@ function SystemEmojiFeature() {
|
||||
|
||||
function PageZoomFeature() {
|
||||
const [pageZoom] = useSetting(settingsAtom, 'pageZoom');
|
||||
// [Gitea #103] Mirror the privacy toggle into the html parser's module flag.
|
||||
const [stripTracking] = useSetting(settingsAtom, 'stripTrackingParams');
|
||||
useEffect(() => {
|
||||
setStripTrackingOnRender(stripTracking);
|
||||
}, [stripTracking]);
|
||||
|
||||
if (pageZoom === 100) {
|
||||
document.documentElement.style.removeProperty('font-size');
|
||||
|
||||
Reference in New Issue
Block a user