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:
parent
9fdb0d3a2e
commit
8da782339e
@ -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" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user