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" }],
|
meta: [{ name: "robots", content: "noindex, nofollow" }],
|
||||||
})
|
})
|
||||||
|
|
||||||
// ─── Passwort-Gate ────────────────────────────────────────────────────
|
// Zugriffsschutz läuft serverseitig via nginx Basic-Auth auf /preview
|
||||||
const PREVIEW_PASSWORD = "rebreak-fags" // TODO vor dem Teilen ändern
|
// (Seite + Bilder). Kein Client-Gate mehr (würde das Passwort ins offene
|
||||||
const unlockedCookie = useCookie<string>("rebreak_preview", {
|
// JS-Bundle schreiben + doppelte Passworteingabe verursachen).
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── Reduced-Motion-respektierende Animationen ────────────────────────
|
// ─── Reduced-Motion-respektierende Animationen ────────────────────────
|
||||||
const reduce = usePreferredReducedMotion()
|
const reduce = usePreferredReducedMotion()
|
||||||
@ -69,32 +54,8 @@ const onboardingSteps = [
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="bg-default min-h-dvh text-default font-sans overflow-x-hidden">
|
<div class="bg-default min-h-dvh text-default font-sans overflow-x-hidden">
|
||||||
<!-- ══════════════ PASSWORT-GATE ══════════════ -->
|
<!-- ══════════════ INHALT (Zugriffsschutz via nginx Basic-Auth) ══════════════ -->
|
||||||
<div v-if="!unlocked" class="min-h-dvh flex flex-col items-center justify-center px-4 text-center">
|
<template>
|
||||||
<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>
|
|
||||||
<header class="sticky top-0 z-30 backdrop-blur-md bg-gray-950/70 border-b border-white/5">
|
<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">
|
<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" />
|
<img src="/app-icon.png" alt="Rebreak" class="w-8 h-8 rounded-lg" />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user