security: fix 6 critical RLS vulns, SHA-256 hash, DSGVO [GELÖSCHT], completed status
Some checks failed
Staging Build / build (push) Has been cancelled

This commit is contained in:
DanielS
2026-07-06 22:39:05 +02:00
parent 3d938d29fc
commit 2d44dd4c58
7 changed files with 139 additions and 22 deletions

View File

@@ -1,6 +1,7 @@
'use server'
import { createClient } from '@/lib/supabase/server'
import { createHash } from 'crypto'
import { createAdminClient } from '@/lib/supabase/admin'
import { revalidatePath } from 'next/cache'
import { sendMail } from '@/utils/mail'
@@ -25,18 +26,12 @@ function generateOrderNumber(): string {
}
/**
* Erstellt einen einfachen deterministischen Hash aus dem Bestell-Snapshot.
* Erstellt einen SHA-256 Hash aus dem Bestell-Snapshot.
* Wird für den Idempotenz-Guard verwendet (verhindert Doppelbestellungen).
*/
function hashOrderSnapshot(snapshot: object): string {
const str = JSON.stringify(snapshot)
let hash = 0
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i)
hash = ((hash << 5) - hash) + char
hash = hash & hash // 32-bit integer
}
return Math.abs(hash).toString(36)
return createHash('sha256').update(str).digest('hex')
}
// ─── submitOrder ──────────────────────────────────────────────────────────────
@@ -155,16 +150,16 @@ export async function submitOrder(params: {
const customerSnapshot = buildCustomerSnapshot(customerProfile, endCustomer ?? null)
const orderSnapshot = buildOrderSnapshot(selections, dbProducts, dbCategories, billingInterval, moduleQuantities, lastLicenseDate)
// 2. Idempotenz-Guard: Prüfen ob identische Bestellung in den letzten 30s existiert
// 2. Idempotenz-Guard: Prüfen ob identische Bestellung in den letzten 5 Minuten existiert
const orderHash = hashOrderSnapshot(orderSnapshot)
const thirtySecondsAgo = new Date(Date.now() - 30_000).toISOString()
const fiveMinutesAgo = new Date(Date.now() - 5 * 60_000).toISOString()
const { data: existingOrder } = await supabase
.from('orders')
.select('*')
.eq('user_id', user.id)
.eq('order_hash', orderHash)
.gte('created_at', thirtySecondsAgo)
.gte('created_at', fiveMinutesAgo)
.maybeSingle()
if (existingOrder) {