refactor(marketing): /preview-Zugriffsschutz via nginx Basic-Auth statt Client-Gate

Client-seitiges Passwort-Gate entfernt: schrieb das Passwort ins offen
erreichbare JS-Bundle (= Leak, identisch zum nginx-PW) und verursachte doppelte
Passworteingabe. Schutz läuft jetzt serverseitig via nginx auf /preview (Seite +
Bilder). Ein Passwort, kein Leak.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
chahinebrini 2026-06-09 05:03:14 +02:00
parent 9fdb0d3a2e
commit 8da782339e

View File

@ -13,24 +13,9 @@ useHead({
meta: [{ name: "robots", content: "noindex, nofollow" }],
})
// Passwort-Gate
const PREVIEW_PASSWORD = "rebreak-fags" // TODO vor dem Teilen ändern
const unlockedCookie = useCookie<string>("rebreak_preview", {
maxAge: 60 * 60 * 24 * 30,
sameSite: "lax",
})
const unlocked = ref(unlockedCookie.value === "1")
const passwordInput = ref("")
const wrong = ref(false)
function tryUnlock() {
if (passwordInput.value.trim() === PREVIEW_PASSWORD) {
unlockedCookie.value = "1"
unlocked.value = true
wrong.value = false
} else {
wrong.value = true
}
}
// Zugriffsschutz läuft serverseitig via nginx Basic-Auth auf /preview
// (Seite + Bilder). Kein Client-Gate mehr (würde das Passwort ins offene
// JS-Bundle schreiben + doppelte Passworteingabe verursachen).
// Reduced-Motion-respektierende Animationen
const reduce = usePreferredReducedMotion()
@ -69,32 +54,8 @@ const onboardingSteps = [
<template>
<div class="bg-default min-h-dvh text-default font-sans overflow-x-hidden">
<!-- PASSWORT-GATE -->
<div v-if="!unlocked" class="min-h-dvh flex flex-col items-center justify-center px-4 text-center">
<div class="absolute inset-0 bg-linear-to-b from-gray-950 via-primary-950/20 to-gray-950 pointer-events-none" />
<div class="relative w-full max-w-sm">
<img src="/app-icon.png" alt="Rebreak" class="w-16 h-16 rounded-2xl mx-auto mb-6 shadow-lg" />
<div class="inline-flex items-center gap-2 bg-primary-950/60 border border-primary-800/40 rounded-full px-4 py-1.5 text-sm text-primary-300 mb-6">
<UIcon name="i-heroicons-lock-closed" class="text-primary-400" />
Geschützte Vorschau
</div>
<h1 class="text-2xl font-black text-highlighted mb-2">Rebreak App-Vorschau</h1>
<p class="text-sm text-muted mb-8">
Diese Seite ist privat. Bitte gib das Passwort ein, das du erhalten hast.
</p>
<form class="flex flex-col gap-3" @submit.prevent="tryUnlock">
<UInput v-model="passwordInput" type="password" size="xl" placeholder="Passwort" autofocus aria-label="Passwort" />
<p v-if="wrong" class="text-sm text-error">Das Passwort stimmt nicht. Bitte versuche es erneut.</p>
<UButton type="submit" size="xl" block class="mt-1">
<UIcon name="i-heroicons-arrow-right-on-rectangle" />
Vorschau öffnen
</UButton>
</form>
</div>
</div>
<!-- INHALT -->
<template v-else>
<!-- INHALT (Zugriffsschutz via nginx Basic-Auth) -->
<template>
<header class="sticky top-0 z-30 backdrop-blur-md bg-gray-950/70 border-b border-white/5">
<div class="max-w-6xl mx-auto px-4 h-14 flex items-center gap-3">
<img src="/app-icon.png" alt="Rebreak" class="w-8 h-8 rounded-lg" />