diff --git a/.github/workflows/buildcheck.yml b/.github/workflows/buildcheck.yml
index 3815961..a2c6a78 100644
--- a/.github/workflows/buildcheck.yml
+++ b/.github/workflows/buildcheck.yml
@@ -4,7 +4,6 @@ on:
pull_request:
branches:
- dev
- - master
jobs:
build:
@@ -49,6 +48,8 @@ jobs:
DIGISTORE_KEY=${{ secrets.DIGISTORE_KEY }}
SPOTIFY_CLIENT_ID=${{ secrets.SPOTIFY_CLIENT_ID }}
SPOTIFY_CLIENT_SECRET=${{ secrets.SPOTIFY_CLIENT_SECRET }}
+ NEXT_PUBLIC_POSTHOG_KEY=${{ secrets.NEXT_PUBLIC_POSTHOG_KEY }}
+ NEXT_PUBLIC_POSTHOG_HOST=${{ secrets.NEXT_PUBLIC_POSTHOG_HOST }}
EOF
- name: Run build
diff --git a/amplify.yml b/amplify.yml
index ab0e9ca..c0287de 100644
--- a/amplify.yml
+++ b/amplify.yml
@@ -5,11 +5,11 @@ frontend:
commands:
# Debug: Zeige alle relevanten Umgebungsvariablen an
- echo "Prüfe Environment Variablen:"
- - env | grep -e DATABASE_URL -e SPOTIFY_CLIENT_ID -e DIGISTORE_KEY -e SPOTIFY_CLIENT_SECRET -e CLOUDFRONT_KEY -e S3_REGION -e COPECART_KEY -e S3_ACCESS_KEY_ID -e S3_SECRET_ACCESS_KEY -e S3_BUCKET_NAME -e OPTIMIZE_API_KEY -e DIRECT_DATABASE_URL -e NEXTAUTH_SECRET -e META_APP_ID -e META_APP_SECRET -e NEXTAUTH_URL -e GOOGLE_CLIENT_ID -e GOOGLE_CLIENT_SECRET -e EMAIL_SERVER_USER -e EMAIL_SERVER_PASSWORD -e EMAIL_SERVER_HOST -e EMAIL_SERVER_PORT -e EMAIL_FROM
+ - env | grep -e DATABASE_URL -e SPOTIFY_CLIENT_ID -e NEXT_PUBLIC_POSTHOG_HOST -e NEXT_PUBLIC_POSTHOG_KEY -e DIGISTORE_KEY -e SPOTIFY_CLIENT_SECRET -e CLOUDFRONT_KEY -e S3_REGION -e COPECART_KEY -e S3_ACCESS_KEY_ID -e S3_SECRET_ACCESS_KEY -e S3_BUCKET_NAME -e OPTIMIZE_API_KEY -e DIRECT_DATABASE_URL -e NEXTAUTH_SECRET -e META_APP_ID -e META_APP_SECRET -e NEXTAUTH_URL -e GOOGLE_CLIENT_ID -e GOOGLE_CLIENT_SECRET -e EMAIL_SERVER_USER -e EMAIL_SERVER_PASSWORD -e EMAIL_SERVER_HOST -e EMAIL_SERVER_PORT -e EMAIL_FROM
# Schreibe Variablen in die .env.production Datei
- echo "Erstelle .env.production Datei"
- - env | grep -e DATABASE_URL -e SPOTIFY_CLIENT_ID -e DIGISTORE_KEY -e SPOTIFY_CLIENT_SECRET -e CLOUDFRONT_KEY -e S3_REGION -e COPECART_KEY -e S3_ACCESS_KEY_ID -e S3_SECRET_ACCESS_KEY -e S3_BUCKET_NAME -e OPTIMIZE_API_KEY -e DIRECT_DATABASE_URL -e NEXTAUTH_SECRET -e META_APP_ID -e META_APP_SECRET -e NEXTAUTH_URL -e GOOGLE_CLIENT_ID -e GOOGLE_CLIENT_SECRET -e EMAIL_SERVER_USER -e EMAIL_SERVER_PASSWORD -e EMAIL_SERVER_HOST -e EMAIL_SERVER_PORT -e EMAIL_FROM > .env.production
+ - env | grep -e DATABASE_URL -e SPOTIFY_CLIENT_ID -e NEXT_PUBLIC_POSTHOG_HOST -e NEXT_PUBLIC_POSTHOG_KEY -e DIGISTORE_KEY -e SPOTIFY_CLIENT_SECRET -e CLOUDFRONT_KEY -e S3_REGION -e COPECART_KEY -e S3_ACCESS_KEY_ID -e S3_SECRET_ACCESS_KEY -e S3_BUCKET_NAME -e OPTIMIZE_API_KEY -e DIRECT_DATABASE_URL -e NEXTAUTH_SECRET -e META_APP_ID -e META_APP_SECRET -e NEXTAUTH_URL -e GOOGLE_CLIENT_ID -e GOOGLE_CLIENT_SECRET -e EMAIL_SERVER_USER -e EMAIL_SERVER_PASSWORD -e EMAIL_SERVER_HOST -e EMAIL_SERVER_PORT -e EMAIL_FROM > .env.production
- echo "Inhalt der .env.production Datei:"
- cat .env.production
diff --git a/middleware.ts b/middleware.ts
new file mode 100644
index 0000000..7705468
--- /dev/null
+++ b/middleware.ts
@@ -0,0 +1,29 @@
+// import { type NextRequest, NextResponse } from "next/server";
+
+// export function middleware(req: NextRequest) {
+// const { pathname } = req.nextUrl;
+
+// // Überwache nur die Startseite
+// if (pathname === "/") {
+// // Beispiel: IP-Adresse und User-Agent speichern
+// const ip = req.ip ?? req.headers.get("x-forwarded-for") ?? "Unbekannt";
+// const userAgent = req.headers.get("user-agent") ?? "Unbekannt";
+
+// console.log(
+// `Besuch auf der Startseite: IP: ${ip}, User-Agent: ${userAgent}`,
+// );
+
+// // Du könntest die Daten auch an einen Tracking-Service senden
+// // await fetch('https://example.com/api/track', {
+// // method: 'POST',
+// // body: JSON.stringify({ ip, userAgent }),
+// // headers: { 'Content-Type': 'application/json' },
+// // });
+// }
+
+// return NextResponse.next();
+// }
+
+// export const config = {
+// matcher: ["/", "/about"], // Hier kannst du festlegen, welche Routen überwacht werden
+// };
diff --git a/package-lock.json b/package-lock.json
index 98b8125..faa7cd9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -50,6 +50,7 @@
"next-view-transitions": "^0.3.2",
"nodemailer": "^6.9.16",
"phenomenon": "^1.6.0",
+ "posthog-js": "^1.207.7",
"react": "^18.3.1",
"react-day-picker": "^8.10.1",
"react-dom": "^18.3.1",
@@ -4890,6 +4891,16 @@
"url": "https://github.com/sponsors/mesqueeb"
}
},
+ "node_modules/core-js": {
+ "version": "3.40.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz",
+ "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==",
+ "hasInstallScript": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -6237,6 +6248,11 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fflate": {
+ "version": "0.4.8",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz",
+ "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA=="
+ },
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -8384,6 +8400,26 @@
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"license": "MIT"
},
+ "node_modules/posthog-js": {
+ "version": "1.207.7",
+ "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.207.7.tgz",
+ "integrity": "sha512-r8etIHrRZOU6T4K/Du7faburFQOvcxFxxN97gouwepi54gVDXoz0y662RCUQWRwtAzUzJlBtYE0degxlhy1Txw==",
+ "dependencies": {
+ "core-js": "^3.38.1",
+ "fflate": "^0.4.8",
+ "preact": "^10.19.3",
+ "web-vitals": "^4.2.0"
+ }
+ },
+ "node_modules/posthog-js/node_modules/preact": {
+ "version": "10.25.4",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.25.4.tgz",
+ "integrity": "sha512-jLdZDb+Q+odkHJ+MpW/9U5cODzqnB+fy2EiHSZES7ldV5LK7yjlVzTp7R8Xy6W6y75kfK8iWYtFVH7lvjwrCMA==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
"node_modules/preact": {
"version": "10.11.3",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz",
@@ -9940,6 +9976,11 @@
"d3-timer": "^3.0.1"
}
},
+ "node_modules/web-vitals": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz",
+ "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw=="
+ },
"node_modules/webpack-bundle-analyzer": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz",
diff --git a/package.json b/package.json
index f2190f0..3dd44d8 100644
--- a/package.json
+++ b/package.json
@@ -57,6 +57,7 @@
"next-view-transitions": "^0.3.2",
"nodemailer": "^6.9.16",
"phenomenon": "^1.6.0",
+ "posthog-js": "^1.207.7",
"react": "^18.3.1",
"react-day-picker": "^8.10.1",
"react-dom": "^18.3.1",
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index cdad1f8..5deb1d4 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -294,6 +294,7 @@ model User {
midCPS Float @default(0.5)
package Package?
admin Boolean @default(false)
+ tester Boolean @default(false)
accounts Account[]
sessions Session[]
projects Project[]
diff --git a/src/app/page.tsx b/src/app/page.tsx
index d7bf544..7d72217 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -5,10 +5,11 @@ import { CTA } from "@/app/_components/landing/cta";
import { Navbar } from "@/app/_components/landing/navbar";
import { Footer } from "@/app/_components/landing/footer";
import { FAQ } from "./_components/landing/faq";
+import { CSPostHogProvider } from "./providers";
export default async function Home() {
return (
- <>
+
@@ -18,6 +19,6 @@ export default async function Home() {
- >
+
);
}
diff --git a/src/app/providers.js b/src/app/providers.js
new file mode 100644
index 0000000..2a3b8b0
--- /dev/null
+++ b/src/app/providers.js
@@ -0,0 +1,16 @@
+"use client";
+import posthog from 'posthog-js'
+import { PostHogProvider } from 'posthog-js/react'
+
+if (typeof window !== 'undefined') {
+ // @ts-expect-error || @ts-ignore
+ posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
+ api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
+ // person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well
+ person_profiles: 'always', // or 'always' to create profiles for anonymous users as well
+ })
+}
+// @ts-expect-error || @ts-ignore
+export function CSPostHogProvider({ children }) {
+ return {children}
+}
\ No newline at end of file
diff --git a/src/env.js b/src/env.js
index 9d11ab3..ae344c7 100644
--- a/src/env.js
+++ b/src/env.js
@@ -42,6 +42,8 @@ export const env = createEnv({
DIGISTORE_KEY: z.string(),
SPOTIFY_CLIENT_ID: z.string(),
SPOTIFY_CLIENT_SECRET: z.string(),
+ POSTHOG_HOST: z.string(),
+ POSTHOG_KEY: z.string(),
},
/**
@@ -82,6 +84,8 @@ export const env = createEnv({
DIGISTORE_KEY: process.env.DIGISTORE_KEY,
SPOTIFY_CLIENT_ID: process.env.SPOTIFY_CLIENT_ID,
SPOTIFY_CLIENT_SECRET: process.env.SPOTIFY_CLIENT_SECRET,
+ POSTHOG_KEY: process.env.NEXT_PUBLIC_POSTHOG_KEY,
+ POSTHOG_HOST: process.env.NEXT_PUBLIC_POSTHOG_HOST,
},
/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially
diff --git a/src/server/api/routers/consent.ts b/src/server/api/routers/consent.ts
index da9a326..0b451e3 100644
--- a/src/server/api/routers/consent.ts
+++ b/src/server/api/routers/consent.ts
@@ -29,6 +29,15 @@ function hashValue(value: string, algorithm = "sha256"): string {
return hash.digest("hex");
}
+function compareHash(
+ originalValue: string,
+ hashedValue: string,
+ algorithm = "sha256",
+): boolean {
+ const newHash = hashValue(originalValue, algorithm);
+ return newHash === hashedValue;
+}
+
export const consentRouter = createTRPCRouter({
update: publicProcedure
.input(