Files
Webklar-Kundenbereich/server/routes/vorschauLink.js
T
ClaudeandClaude Opus 5.5 2873638b1c Geheimer Vorschau-Link: /vorschau/<subdomain>/<token> setzt ein Cookie nur fuer diese Preview
- websiteProjects.shareToken (scripts/vorschau-link-setup.mjs)
- POST/DELETE /api/admin/website-projects/:id/vorschau-link fuer Mitarbeiter (neu erzeugen / abschalten)
- GET /api/vorschau-link/pruefen fuer die Login-Pruefung der Previews (preview-portal /auth/verify)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 17:59:23 +00:00

60 lines
2.8 KiB
JavaScript

import { Router } from 'express'
import { checkShare, cookieName, previewUrl, shareCookieOptions } from '../services/vorschauLink.js'
// Geheimer Vorschau-Link, siehe services/vorschauLink.js
function seite(res, status, titel, text) {
res
.status(status)
.set('Cache-Control', 'no-store')
.set('X-Robots-Tag', 'noindex, nofollow')
.type('html')
.send(`<!doctype html>
<html lang="de"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow"><title>${titel}</title>
<style>body{font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;background:#f6f7fb;color:#1a1f36;margin:0;display:grid;place-items:center;min-height:100vh;padding:16px;box-sizing:border-box}
main{background:#fff;border-radius:12px;padding:32px;max-width:420px;box-shadow:0 1px 3px rgba(0,0,0,.08)}h1{font-size:20px;margin:0 0 12px}p{margin:0;line-height:1.5;color:#4f566b}</style>
</head><body><main><h1>${titel}</h1><p>${text}</p></main></body></html>`)
}
/** Seite: GET /vorschau/:subdomain/:token -> Cookie setzen und auf die Preview weiterleiten */
export function vorschauLinkSeite() {
const router = Router()
router.get('/:subdomain/:token', async (req, res) => {
let result
try {
result = await checkShare(req.params.subdomain, req.params.token)
} catch (err) {
console.error('[vorschau-link] Pruefung fehlgeschlagen:', err.message)
return seite(res, 500, 'Vorschau nicht erreichbar', 'Bitte in ein paar Minuten noch einmal versuchen.')
}
if (result.reason === 'not_ready') {
return seite(res, 503, 'Vorschau wird vorbereitet', 'Die Seite wird gerade gebaut. Bitte in ein paar Minuten noch einmal versuchen.')
}
if (!result.allowed) {
return seite(res, 404, 'Link nicht gültig', 'Dieser Vorschau-Link ist nicht (mehr) gültig. Bitte frag bei WEBklar nach einem neuen Link.')
}
res.cookie(cookieName(result.subdomain), req.params.token, shareCookieOptions())
res.set('Cache-Control', 'no-store')
res.set('Referrer-Policy', 'no-referrer')
return res.redirect(302, previewUrl(result.subdomain))
})
return router
}
/** Fuer die Login-Pruefung der Previews: GET /api/vorschau-link/pruefen?subdomain=..., Header x-vorschau-token */
export function vorschauLinkPruefung() {
const router = Router()
router.get('/pruefen', async (req, res) => {
res.set('Cache-Control', 'no-store')
try {
const result = await checkShare(req.query.subdomain, req.get('x-vorschau-token'))
return res.status(result.allowed ? 200 : 403).json({ allowed: result.allowed, reason: result.reason })
} catch (err) {
console.error('[vorschau-link] Pruefung fehlgeschlagen:', err.message)
return res.status(500).json({ allowed: false })
}
})
return router
}