From d605d17d06a3199f647defb774725dd1b62e68b5 Mon Sep 17 00:00:00 2001 From: valentinkolb Date: Mon, 4 Nov 2024 23:10:19 +0100 Subject: [PATCH] feat(whatWeKnowAboutYou): finished whatWeKnowAboutYou Seite --- src/components/analytics/index.tsx | 2 +- .../CollectedAnalyticsData.tsx | 235 +++++++++++++++++ .../whatWeKnowAboutYou/CollectedUserData.tsx | 84 ++++++ .../util/whatWeKnowAboutYou/DataItem.tsx | 31 +++ src/pages/util/whatWeKnowAboutYou/index.tsx | 243 +----------------- 5 files changed, 357 insertions(+), 238 deletions(-) create mode 100644 src/pages/util/whatWeKnowAboutYou/CollectedAnalyticsData.tsx create mode 100644 src/pages/util/whatWeKnowAboutYou/CollectedUserData.tsx create mode 100644 src/pages/util/whatWeKnowAboutYou/DataItem.tsx diff --git a/src/components/analytics/index.tsx b/src/components/analytics/index.tsx index 12efa8b..c234c3c 100644 --- a/src/components/analytics/index.tsx +++ b/src/components/analytics/index.tsx @@ -33,7 +33,7 @@ export default function Analytics() {
+ + + + +} + +export default function CollectedAnalyticsData() { + + const {pb} = usePB() + + const location = useLocation() + + const [cookies] = useCookies([ANALYTICS_COOKIE_NAME]) + const cookieValue = cookies[ANALYTICS_COOKIE_NAME] + + const parserResult = new UAParser().getResult() + + const preferredLanguage = usePreferredLanguage() + + const ipQuery = useQuery({ + queryKey: ['ip'], + queryFn: async () => { + return await ofetch(ANALYTICS_IP_API, {ignoreResponseError: true}) + } + }) + + const visitorIdQuery = useQuery({ + queryKey: ['visitorId', cookieValue], + queryFn: async () => { + const res = await pb.collection("analyticsVisitors").getOne(cookieValue) + + return { + activeSince: res?.created, + } + }, + enabled: !!cookieValue + }) + + return ( +
+
+ Anonyme Analysedaten +
+ +
+ + Alle Analysedaten, die wir sammeln, sind anonymisiert und dienen dazu, diesen Dienst zu + verbessern + und zu personalisieren. +
+ Wir geben keine Daten an Dritte weiter. Die Daten liegen auf unseren eigenen Servern in + Deutschland. +
+ Nur Systemadministratoren haben Zugriff auf die Daten. Wir sammeln diese Daten erst, nachdem + Cookies + akzeptiert wurden. +
+
+ + + + {!cookieValue && ( + + Solange du keine Cookies akzeptierst, sammeln wir keine Analysedaten. + + )} + + + { + [ + { + icon: IconId, + title: "Analyse-ID", + data: cookieValue ?? "-", + description: <> + Du bist mit dieser ID aktiv + seit {pprintDate(visitorIdQuery.data?.activeSince ?? "")}. + Seit diesem Datum sammeln wir Analysedaten verknüpft mit dieser ID. +
+ Auf Basis dieser ID können wir die gespeicherten Analysedaten aggregieren und + analysieren. + + }, + { + icon: IconSlash, + title: "Aktuelle Seite", + data: location.pathname, + description: "Der Pfad der aktuellen Seite, die du besuchst. Wir speichern diese Pfade um zu analysieren, welche Seiten am häufigsten besucht werden und wie Nutzende navigieren." + }, + { + icon: IconBug, + title: "Fehler", + data: "-", + description: "Falls ein Fehler auftritt speichern wir die Fehlermeldung und den Zeitpunkt und dem entsprechenden Pfad, um die Stabilität der Seite zu verbessern." + }, + { + icon: IconWorldWww, + title: "IP Adresse", + data: ipQuery.data?.ip || "-", + description: <> + Deine IP Adresse wird genutzt, um das Land zu bestimmen, aus dem du die Seite + besuchst. +
+ Folgende Daten können darüber hinaus anhand deiner IP Adresse bestimmt werden, werden + aber nicht + gespeichert: + Bundesland, Stadt, ungefährer Standort, Internetanbieter. + + }, + { + icon: IconGlobe, + title: "Land", + data: ipQuery.data?.country_code || "-", + description: "Das Land, aus dem du die Seite besuchst. Diese Information wird genutzt, um die Seite zu personalisieren und um zu verstehen, woher die Nutzenden kommen." + }, + { + icon: () => , + title: "Browser", + data: `${parserResult.browser.name} ${parserResult.browser.version}`, + description: "Dein Browser wird genutzt, um die Seite anzuzeigen. Diese Information wird genutzt, um die Seite zu optimieren und um zu verstehen, welche Technologien Nutzende verwenden." + }, + { + icon: () => , + title: "Betriebssystem", + data: `${parserResult.os.name} ${parserResult.os.version}`, + description: "Dein Betriebssystem wird genutzt, um die Seite anzuzeigen. Diese Information wird genutzt, um die Seite zu optimieren und um zu verstehen, welche Technologien Nutzende verwenden." + }, + { + icon: IconWorldWww, + title: "Bevorzugte Sprache", + data: preferredLanguage || "-", + description: "Deine bevorzugte Sprache wird genutzt, um zu verstehen, welche Sprachen Nutzende sprechen." + }, + { + icon: () => , + title: "Gerätetyp", + data: parserResult.device.type || "desktop", + description: "Dein Gerätetyp wird genutzt, um die Seite anzuzeigen. Diese Information wird genutzt, um die Seite zu optimieren und um zu verstehen, welche Technologien Nutzende verwenden." + } + + ].map((feature, index) => ( + + )) + } +
+
+ ) +} \ No newline at end of file diff --git a/src/pages/util/whatWeKnowAboutYou/CollectedUserData.tsx b/src/pages/util/whatWeKnowAboutYou/CollectedUserData.tsx new file mode 100644 index 0000000..0512fb8 --- /dev/null +++ b/src/pages/util/whatWeKnowAboutYou/CollectedUserData.tsx @@ -0,0 +1,84 @@ +import {usePB} from "@/lib/pocketbase.tsx"; +import {Center, SimpleGrid, Text, Title} from "@mantine/core"; +import {IconCalendarClock, IconGlobe, IconPassword, IconSignature, IconUser, IconUsers} from "@tabler/icons-react"; +import {getUserName} from "@/components/users/modals/util.tsx"; +import {LdapGroupModel} from "@/models/AuthTypes.ts"; +import DataItem from "@/pages/util/whatWeKnowAboutYou/DataItem.tsx"; + +export default function CollectedUserData() { + const {user} = usePB() + + if (!user) return null + + return ( +
+ +
+ Accountdaten +
+ +
+ + Wenn du einen Account hast speichern wir zusätzlich zu den anonymen Analysedaten auch deine + Accountdaten. + +
+ + + { + [ + { + icon: IconUser, + title: "Anmeldename und Realm", + data: `${user.username} (${user.REALM})`, + description: "Hiermit kannst du dich anmelden und deine Daten verwalten. Deine Realm wird genutzt, um zu bestimmen ob du einen StuVe-IT oder Gast-Account hast." + }, + { + icon: IconPassword, + title: "Passwort", + data: '***********', + description: "Dein Passwort wird verschlüsselt auf unseren Servern gespeichert und kann nicht eingesehen werden." + }, + { + icon: IconGlobe, + title: "E-Mail", + data: user.email, + description: "Deine E-Mail Adresse wird genutzt, um dich zu kontaktieren. Andere Nutzende können deine E-Mail Adresse nicht sehen." + }, + { + icon: IconSignature, + title: "Name", + data: getUserName(user), + description: "Dein Name wird genutzt, um dich zu identifizieren. Andere Nutzende können deinen Namen sehen." + }, + { + icon: IconCalendarClock, + title: "Account Ablaufdatum", + data: user?.accountExpires ? ( + new Date(user?.accountExpires).getTime() > Date.now() ? ( + "Account ist aktiv und läuft am " + new Date(user?.accountExpires).toLocaleDateString() + " ab" + ) : ( + "Account ist abgelaufen" + ) + ) : ( + "Dein Account läuft nicht ab" + ), + description: "Dein Account-Ablaufdatum wird genutzt, um zu bestimmen, ob dein Account noch aktiv ist." + }, + { + icon: IconUsers, + title: "Gruppen", + data: user?.expand?.memberOf.map((group: LdapGroupModel) => group.cn).join(", ") || "Keine Gruppen", + description: "Dein Account-Ablaufdatum wird genutzt, um zu bestimmen, ob dein Account noch aktiv ist." + }, + + ].map((feature, index) => ( + + )) + } + +
+ ) +} \ No newline at end of file diff --git a/src/pages/util/whatWeKnowAboutYou/DataItem.tsx b/src/pages/util/whatWeKnowAboutYou/DataItem.tsx new file mode 100644 index 0000000..4e3fb47 --- /dev/null +++ b/src/pages/util/whatWeKnowAboutYou/DataItem.tsx @@ -0,0 +1,31 @@ +import {FC, ReactNode} from "react"; +import {Code, rem, Text, ThemeIcon} from "@mantine/core"; + +interface FeatureProps { + // eslint-disable-next-line + icon: FC; + data: ReactNode; + title: ReactNode; + description: ReactNode; +} + +export default function DataItem({icon: Icon, data, title, description}: FeatureProps) { + return ( +
+ + + + + {title} + + + + {data} + + + + {description} + +
+ ) +} \ No newline at end of file diff --git a/src/pages/util/whatWeKnowAboutYou/index.tsx b/src/pages/util/whatWeKnowAboutYou/index.tsx index 0765ebd..bcfbfcf 100644 --- a/src/pages/util/whatWeKnowAboutYou/index.tsx +++ b/src/pages/util/whatWeKnowAboutYou/index.tsx @@ -1,81 +1,11 @@ -import {Alert, Anchor, Center, Code, rem, SimpleGrid, Text, ThemeIcon, Title} from "@mantine/core"; -import {usePB} from "@/lib/pocketbase.tsx"; -import {FC, ReactNode} from "react"; -import { - IconBug, - IconCalendarClock, - IconGlobe, - IconId, - IconPassword, - IconSignature, - IconSlash, - IconUser, - IconUsers, - IconWorldWww -} from "@tabler/icons-react"; -import {useCookies} from "react-cookie"; -import {ANALYTICS_COOKIE_NAME, ANALYTICS_IP_API} from "../../../../config.ts"; -import {Link, useLocation} from "react-router-dom"; -import {ofetch} from "ofetch"; -import {AnalyticsIpApiResult} from "@/models/AnalyticsTypes.ts"; -import {useQuery} from "@tanstack/react-query"; -import {UAParser} from "ua-parser-js"; -import { - BrowserIcon, - DeviceTypeIcon, - OsIcon -} from "@/pages/admin/AnalyticsDashboard/AnalyticsSessions/AnalyticsSessionRow.tsx"; -import {usePreferredLanguage} from "@uidotdev/usehooks"; -import {getUserName} from "@/components/users/modals/util.tsx"; -import {LdapGroupModel} from "@/models/AuthTypes.ts"; +import {Anchor, Center, Title} from "@mantine/core"; +import {Link} from "react-router-dom"; +import CollectedAnalyticsData from "@/pages/util/whatWeKnowAboutYou/CollectedAnalyticsData.tsx"; +import CollectedUserData from "@/pages/util/whatWeKnowAboutYou/CollectedUserData.tsx"; -interface FeatureProps { - icon: FC; - data: ReactNode; - title: ReactNode; - description: ReactNode; -} - -function DataItem({icon: Icon, data, title, description}: FeatureProps) { - return ( -
- - - - - {title} - - - - {data} - - - - {description} - -
- ) -} export default function WhatWeKnowAboutYou() { - const {user} = usePB() - const location = useLocation() - - const [cookies] = useCookies([ANALYTICS_COOKIE_NAME]) - const cookieValue = cookies[ANALYTICS_COOKIE_NAME] - - const parserResult = new UAParser().getResult() - - const preferredLanguage = usePreferredLanguage() - - const ipQuery = useQuery({ - queryKey: ['ip'], - queryFn: async () => { - return await ofetch(ANALYTICS_IP_API, {ignoreResponseError: true}) - } - }) - return <>
@@ -92,169 +22,8 @@ export default function WhatWeKnowAboutYou() {
-
+ -
- Anonyme Analysedaten -
- -
- - - Alle Analysedaten, die wir sammeln, sind anonymisiert und dienen dazu, diesen Dienst zu verbessern - und zu personalisieren. -
- Wir geben keine Daten an Dritte weiter. Die Daten liegen auf unseren eigenen Servern in Deutschland. -
- Nur Systemadministratoren haben Zugriff auf die Daten. Wir sammeln diese Daten erst, nachdem Cookies - akzeptiert wurden. -
-
- - {!cookieValue && ( - - Solange du keine Cookies akzeptierst, sammeln wir keine Analysedaten. - - )} - - - { - [ - { - icon: IconId, - title: "Analyse-ID", - data: cookieValue || "-", - description: "Diese ID wird genutzt, um nachzuvollziehen, wie du über die Zeit verteilt die StuVe IT Tools nutzt." - }, - { - icon: IconSlash, - title: "Aktuelle Seite", - data: location.pathname, - description: "Der Pfad der aktuellen Seite, die du besuchst. Wir speichern diese Pfade um zu analysieren, welche Seiten am häufigsten besucht werden und wie Nutzende navigieren." - }, - { - icon: IconBug, - title: "Fehler", - data: "-", - description: "Falls ein Fehler auftritt speichern wir die Fehlermeldung und den Zeitpunkt und dem entsprechenden Pfad, um die Stabilität der Seite zu verbessern." - }, - { - icon: IconWorldWww, - title: "IP Adresse", - data: ipQuery.data?.ip || "-", - description: "Deine IP Adresse wird genutzt, um das Land zu bestimmen, aus dem du die Seite besuchst." - }, - { - icon: IconGlobe, - title: "Land", - data: ipQuery.data?.country_code || "-", - description: "Das Land, aus dem du die Seite besuchst. Diese Information wird genutzt, um die Seite zu personalisieren und um zu verstehen, woher die Nutzenden kommen." - }, - { - icon: () => , - title: "Browser", - data: `${parserResult.browser.name} ${parserResult.browser.version}`, - description: "Dein Browser wird genutzt, um die Seite anzuzeigen. Diese Information wird genutzt, um die Seite zu optimieren und um zu verstehen, welche Technologien Nutzende verwenden." - }, - { - icon: () => , - title: "Betriebssystem", - data: `${parserResult.os.name} ${parserResult.os.version}`, - description: "Dein Betriebssystem wird genutzt, um die Seite anzuzeigen. Diese Information wird genutzt, um die Seite zu optimieren und um zu verstehen, welche Technologien Nutzende verwenden." - }, - { - icon: IconWorldWww, - title: "Bevorzugte Sprache", - data: preferredLanguage || "-", - description: "Deine bevorzugte Sprache wird genutzt, um zu verstehen, welche Sprachen Nutzende sprechen." - }, - { - icon: () => , - title: "Gerätetyp", - data: parserResult.device.type || "desktop", - description: "Dein Gerätetyp wird genutzt, um die Seite anzuzeigen. Diese Information wird genutzt, um die Seite zu optimieren und um zu verstehen, welche Technologien Nutzende verwenden." - } - - ].map((feature, index) => ( - - )) - } - -
- - { - user && -
- -
- Accountdaten -
- -
- - Wenn du einen Account hast speichern wir zusätzlich zu den anonymen Analysedaten auch deine - Accountdaten. - -
- - - { - [ - { - icon: IconUser, - title: "Anmeldename und Realm", - data: `${user.username} (${user.REALM})`, - description: "Hiermit kannst du dich anmelden und deine Daten verwalten. Deine Realm wird genutzt, um zu bestimmen ob du einen StuVe-IT oder Gast-Account hast." - }, - { - icon: IconPassword, - title: "Passwort", - data: '***********', - description: "Dein Passwort wird verschlüsselt auf unseren Servern gespeichert und kann nicht eingesehen werden." - }, - { - icon: IconGlobe, - title: "E-Mail", - data: user.email, - description: "Deine E-Mail Adresse wird genutzt, um dich zu kontaktieren. Andere Nutzende können deine E-Mail Adresse nicht sehen." - }, - { - icon: IconSignature, - title: "Name", - data: getUserName(user), - description: "Dein Name wird genutzt, um dich zu identifizieren. Andere Nutzende können deinen Namen sehen." - }, - { - icon: IconCalendarClock, - title: "Account Ablaufdatum", - data: user?.accountExpires ? ( - new Date(user?.accountExpires).getTime() > Date.now() ? ( - "Account ist aktiv und läuft am " + new Date(user?.accountExpires).toLocaleDateString() + " ab" - ) : ( - "Account ist abgelaufen" - ) - ) : ( - "Dein Account läuft nicht ab" - ), - description: "Dein Account-Ablaufdatum wird genutzt, um zu bestimmen, ob dein Account noch aktiv ist." - }, - { - icon: IconUsers, - title: "Gruppen", - data: user?.expand?.memberOf.map((group: LdapGroupModel) => group.cn).join(", ") || "Keine Gruppen", - description: "Dein Account-Ablaufdatum wird genutzt, um zu bestimmen, ob dein Account noch aktiv ist." - }, - - ].map((feature, index) => ( - - )) - } - -
- } + } \ No newline at end of file