From 3a167056147725f37673372448dad607f95a6087 Mon Sep 17 00:00:00 2001 From: elpatron Date: Tue, 13 Jan 2026 12:14:17 +0100 Subject: [PATCH] refactor(push): load VAPID key from server at runtime --- Dockerfile | 4 ---- README.md | 6 ++---- app/actions/subscription.ts | 4 ++++ components/push-manager.tsx | 42 ++++++++++++++++++++++++++----------- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/Dockerfile b/Dockerfile index f7d8d51..4fc7e06 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,10 +12,6 @@ COPY . . # Use a temporary DB for generation ENV DATABASE_URL="file:./temp.db" -# Build arguments for public env vars -ARG NEXT_PUBLIC_VAPID_PUBLIC_KEY -ENV NEXT_PUBLIC_VAPID_PUBLIC_KEY=$NEXT_PUBLIC_VAPID_PUBLIC_KEY - RUN npx prisma generate RUN npm run build diff --git a/README.md b/README.md index b881551..a56276b 100644 --- a/README.md +++ b/README.md @@ -73,10 +73,8 @@ docker-compose up -d --build Mit **Docker CLI**: ```bash -# Image bauen (Beachte: Public Vars müssen beim Build da sein!) -docker build \ - --build-arg NEXT_PUBLIC_VAPID_PUBLIC_KEY="DEIN_PUBLIC_KEY" \ - -t cat-sitting-planner . +# Image bauen +docker build -t cat-sitting-planner . # Container starten # Container starten diff --git a/app/actions/subscription.ts b/app/actions/subscription.ts index 42127eb..313bf41 100644 --- a/app/actions/subscription.ts +++ b/app/actions/subscription.ts @@ -43,3 +43,7 @@ export async function unsubscribeUser(endpoint: string) { return { success: true }; } + +export async function getVapidPublicKey() { + return process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY; +} diff --git a/components/push-manager.tsx b/components/push-manager.tsx index 378c39f..31017b2 100644 --- a/components/push-manager.tsx +++ b/components/push-manager.tsx @@ -3,7 +3,7 @@ import { useState, useEffect } from "react" import { Bell, BellOff, Loader2, AlertTriangle } from "lucide-react" import { toast } from "sonner" -import { subscribeUser, unsubscribeUser } from "@/app/actions/subscription" +import { subscribeUser, unsubscribeUser, getVapidPublicKey } from "@/app/actions/subscription" import { Button } from "@/components/ui/button" function urlBase64ToUint8Array(base64String: string) { @@ -31,20 +31,34 @@ export function PushSubscriptionSettings({ planId }: { planId: string }) { const [subscription, setSubscription] = useState(null) const [loading, setLoading] = useState(false) const [debugInfo, setDebugInfo] = useState(null) + const [vapidKey, setVapidKey] = useState(null) useEffect(() => { - const checks = [] - if (!('serviceWorker' in navigator)) checks.push("No Service Worker support") - if (!('PushManager' in window)) checks.push("No PushManager support") - if (!process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY) checks.push("Missing VAPID Key") + async function checkSupport() { + const checks = [] + if (!('serviceWorker' in navigator)) checks.push("No Service Worker support") + if (!('PushManager' in window)) checks.push("No PushManager support") - if (checks.length === 0) { - setIsSupported(true) - registerServiceWorker() - } else { - console.warn("Push not supported:", checks.join(", ")) - setDebugInfo(checks.join(", ")) + try { + const key = await getVapidPublicKey() + if (!key) { + checks.push("Missing VAPID Key (Server)") + } else { + setVapidKey(key) + } + } catch (e) { + checks.push("Failed to fetch VAPID Key") + } + + if (checks.length === 0) { + setIsSupported(true) + registerServiceWorker() + } else { + console.warn("Push not supported:", checks.join(", ")) + setDebugInfo(checks.join(", ")) + } } + checkSupport() }, []) async function registerServiceWorker() { @@ -59,6 +73,10 @@ export function PushSubscriptionSettings({ planId }: { planId: string }) { } async function subscribe() { + if (!vapidKey) { + toast.error("VAPID Key missing") + return + } setLoading(true) setDebugInfo(null) try { @@ -84,7 +102,7 @@ export function PushSubscriptionSettings({ planId }: { planId: string }) { const sub = await registration.pushManager.subscribe({ userVisibleOnly: true, - applicationServerKey: urlBase64ToUint8Array(process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!) + applicationServerKey: urlBase64ToUint8Array(vapidKey) }) console.log("Subscribed locally:", sub)