feat(cmp): Phase 3 — backend consent withdrawal + consent_id tracking
- ConsentBanner: save consent_id to localStorage after successful POST
- Footer: DELETE /api/consent/{id} on consent re-open (Art. 17 DSGVO)
- New proxy route: DELETE /api/consent/[id] → backend withdrawal endpoint
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
const BACKEND_URL = process.env.CONSENT_BACKEND_URL || 'https://macmini:3007/api/sdk/v1/banner'
|
||||
const TENANT_ID = process.env.CONSENT_TENANT_ID || '9282a473-5c95-4b3a-bf78-0ecc0ec71d3e'
|
||||
|
||||
export async function DELETE(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
||||
try {
|
||||
const { id } = await params
|
||||
const res = await fetch(`${BACKEND_URL}/consent/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: { 'X-Tenant-ID': TENANT_ID },
|
||||
})
|
||||
const data = await res.text()
|
||||
return new NextResponse(data, {
|
||||
status: res.status,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
} catch {
|
||||
return NextResponse.json({ error: 'Consent service not reachable' }, { status: 503 })
|
||||
}
|
||||
}
|
||||
@@ -127,12 +127,12 @@ function detectCookies(): CookieEntry[] {
|
||||
return cookies
|
||||
}
|
||||
|
||||
async function sendConsent(consent: ConsentState, method: ConsentMethod, vendorConsents?: Record<string, boolean>) {
|
||||
async function sendConsent(consent: ConsentState, method: ConsentMethod, vendorConsents?: Record<string, boolean>): Promise<string | null> {
|
||||
try {
|
||||
const { device_type, browser, os } = detectDevice()
|
||||
const { blocked, released } = detectScripts()
|
||||
const cookies_set = detectCookies()
|
||||
await fetch('/api/consent', {
|
||||
const res = await fetch('/api/consent', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
@@ -161,8 +161,14 @@ async function sendConsent(consent: ConsentState, method: ConsentMethod, vendorC
|
||||
cookies_set,
|
||||
}),
|
||||
})
|
||||
const result = await res.json().catch(() => null)
|
||||
if (result?.id) {
|
||||
localStorage.setItem('bp_consent_id', result.id)
|
||||
return result.id
|
||||
}
|
||||
return null
|
||||
} catch {
|
||||
// Consent API not reachable — store locally anyway
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,12 @@ import { Cookie } from 'lucide-react'
|
||||
import { t } from '@/lib/content'
|
||||
import { useApp } from '@/lib/context'
|
||||
|
||||
function reopenConsentBanner() {
|
||||
async function reopenConsentBanner() {
|
||||
const consentId = localStorage.getItem('bp_consent_id')
|
||||
if (consentId) {
|
||||
fetch(`/api/consent/${consentId}`, { method: 'DELETE' }).catch(() => {})
|
||||
localStorage.removeItem('bp_consent_id')
|
||||
}
|
||||
localStorage.removeItem('bp_consent')
|
||||
window.location.reload()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user