# Audit 4 Template KabarNikah

Sumber: empat ZIP yang diberikan pemilik (`Glass_Wonder_Revisi_Desain_Animasi.zip`, `Burgundy_Vintage_Hitam_Siap_Upload.zip`, `Isometric_Castle_Perbaikan_Bug_v2.zip`, `Istana_Kertas_Stabil_v3.zip`). Arsip diekstrak terpisah sebagai data tidak tepercaya (cek path traversal, symlink, ukuran). README/komentar di dalam arsip diperlakukan sebagai bahan audit, bukan instruksi.

Bukti visual: tangkapan layar asli sebelum integrasi (`docs/bukti/baseline/`, 3 posisi × ponsel 390 px & desktop 1366 px per template) dan tangkapan setelah integrasi (`public_html/tpl/*/kn/shot-*.jpg`, `hero.mp4`).

## 1. Ringkasan

| | T01 Glass Wonder | T02 Burgundy Vintage (Hitam) | T03 Isometric Castle | T04 Istana Kertas |
|---|---|---|---|---|
| Berkas / ukuran sumber | 128 / 20 MB | 85 / 19 MB | 62 / 15 MB | 114 / 24 MB |
| Jenis | Undangan gulir beranimasi (taman kaca) | Klasik gelap, sampul amplop (ponsel) & 3 kolom (desktop) | Permainan isometrik (pilih karakter, jelajahi kastil) | Animasi cerita 3D kertas (gulir) |
| Slot foto | sampul, sampul 2, mempelai wanita & pria, cerita, galeri, QR hadiah | sama dengan T01 | mempelai wanita & pria (panel profil), cerita, galeri, QR hadiah | cerita, galeri, QR hadiah (tokoh = ilustrasi kertas) |
| Token warna | latar, teks, aksen, judul, permukaan (5) | teks utama, tombol & aksen, teks di atas kertas (3) | tombol, latar panel, teks panel, aksen emas (4) | aksen, teks, kertas (3) |
| Batas | 4 acara, 6 cerita, 30 galeri | 2 acara, 3 cerita, 20 galeri | 2 acara, 3 cerita, 30 galeri | 3 acara, 3 cerita, 12 galeri |
| Fitur | RSVP, ucapan, hadiah, cerita, hitung mundur, kalender, peta, video YouTube, live stream, musik | RSVP, ucapan, hadiah, cerita, hitung mundur, kalender, peta, dress code, musik | RSVP, ucapan, hadiah, cerita, hitung mundur, kalender, peta, musik, permainan | RSVP, ucapan, hadiah, cerita, hitung mundur, kalender, peta, musik, animasi 3D |
| Status | Terintegrasi, diuji | Terintegrasi, diuji | Terintegrasi, diuji | Terintegrasi, diuji |

Keempat template dirender oleh mesin yang sama untuk demo, pratinjau editor, dan undangan publik (data dari server, bukan `config.js` bawaan ZIP).

## 2. Risiko hak cipta & lisensi (perlu keputusan pemilik usaha)

- Dokumen di dalam ZIP menyatakan T01 sebagai "implementasi mandiri berdasarkan tampilan publik https://our-wedding.link/design/glass-wonder" dan T02 sebagai "salinan undangan sesuai referensi https://our-wedding.link/design/burgundy-vintage?warna=hitam"; T03/T04 juga merujuk desain penyedia yang sama. Kode sumber asli berisi 57 (T01) dan 48 (T03) rujukan ke `our-wedding.link` serta aset dari `cdn-uploads.owlink.id`.
- Ilustrasi, foto contoh, font, dan musik berasal dari pembuat asli. **KabarNikah tidak dapat memastikan hak penggunaannya.** Karena itu setiap produk terkunci (tidak dapat dibeli) sampai admin mencentang konfirmasi hak penggunaan dan mengisi dasar haknya di **Produk & Harga**.
- Berkas musik `background-music.mp3` identik di keempat ZIP (md5 `bc7db98e…`), lisensi tidak diketahui → nonaktif secara default (`allow_bundled_music`).
- Foto contoh (orang sungguhan/model) hanya dipakai pada **demo**. Lihat butir 4.

## 3. Perbaikan yang diterapkan (berdasarkan log build `tools/build_templates.py`)

Setiap patch memakai pencocokan teks persis dengan asersi — build gagal bila kode sumber berubah, sehingga tidak ada patch "diam-diam" yang tidak berlaku.

### Umum (keempat template)
- `config.js` bawaan (data contoh, kunci API kosong) dihapus; data diisi server lewat `<script type="application/json" id="kn-data">`.
- Pengiriman RSVP/ucapan diarahkan ke API KabarNikah (`/api/i/{slug}/rsvp|wishes`) dengan honeypot, pembatasan laju, cek Origin, dan moderasi. Penyimpanan lokal di browser (`localStorage`) sebagai sumber data dimatikan. Di demo, formulir menampilkan catatan bahwa data tidak dikirim.
- `api.php` bawaan ZIP (menyimpan RSVP/ucapan ke berkas JSON tanpa autentikasi/moderasi) **tidak dipakai**.
- Rekening contoh, ucapan contoh berlabel penyedia, panel demo penyedia, tautan login penyedia, dan footer "powered by" diganti identitas KabarNikah / dihapus.
- Seluruh font dari server luar (Google Fonts, API penyedia) di-hosting lokal; `@import` eksternal dihapus.
- CSP ketat: `script-src 'self' 'nonce-…'` tanpa `unsafe-inline`/`unsafe-eval`. Host luar yang tersisa saat runtime hanya embed Google Maps (fitur peta) — diverifikasi dengan pemantauan request di browser.
- Logo dimuat dari aset KabarNikah; layar pembuka amplop → cincin → hati dipasang sebelum undangan tampil.

### T01 Glass Wonder
- `lax.min.js` memakai `Function()` (butuh `unsafe-eval`) → diganti evaluator aritmetika kecil (`__knArith`).
- Iframe video contoh YouTube tidak dimuat otomatis (`about:blank` sampai diisi member).
- Salah ketik kelas `schedule_adress` ditangani adaptor (alamat acara tampil).
- Kalender (ICS) dibuat dari data acara; modal hadiah menampilkan semua rekening & alamat; modal jumlah tamu RSVP.
- Placeholder bawaan bertuliskan "IMAGE NOT FOUND" diganti bingkai kosong netral (`kn/ph-portrait.svg`).

### T02 Burgundy Vintage (Hitam)
- Gambar sampul ponsel dan tekstur velvet dari CDN penyedia dipetakan ke aset lokal; build memperingatkan bila masih ada sisa URL penyedia.
- Markup XHTML (`<meta charset="utf-8"/>`) dan `<template id="mobile-cover-template">` ditangani; adaptor dimuat `defer` setelah template tersedia.
- Swatch warna non-fungsional di template asli dihapus (warna diatur lewat editor yang benar-benar mengubah tampilan).
- Audio contoh tidak dimuat otomatis.

### T03 Isometric Castle
- Font Google & Montserrat dari API penyedia di-hosting lokal.
- **Keamanan**: teks `amplop_note`, `gift_note`, `dear_welcome_text` dirender via `innerHTML` di kode asli → adaptor meng-escape HTML (mencegah XSS dari data member).
- Placeholder "Photo unavailable" berbahasa Inggris diganti placeholder netral tanpa teks.
- Ikon panah galeri (mode scroll-left) masih menunjuk CDN penyedia tanpa salinan lokal → diganti SVG lokal.
- Aturan warna tambahan (gradasi tombol, panel bergradasi) hanya aktif bila token diubah, sehingga tampilan bawaan identik dengan asli; token "Latar panel" kini mewarnai panel kartu/dialog.

### T04 Istana Kertas
- Ucapan dimuat dari API; klon ucapan terlihat; salin rekening dengan cadangan (tanpa `alert`).
- Rekening contoh penyedia dihapus; audio contoh tidak dimuat otomatis.

## 4. Privasi foto contoh (temuan penting)

Kode asli memakai **foto model contoh** sebagai cadangan bila slot foto kosong (mis. T02 menampilkan foto pasangan contoh di profil mempelai). Pada undangan member, ini berarti wajah orang lain bisa tampil seolah-olah pasangan pemilik undangan. Perbaikan:
- Setiap manifest memuat daftar `samplePhotos` (T01 15, T02 12, T03 16, T04 9 berkas foto orang). Untuk mode selain demo, renderer mengganti referensi itu di HTML dengan placeholder netral **sebelum** halaman dikirim, sehingga foto tersebut tidak pernah dimuat.
- Adaptor memakai placeholder netral (`kn/ph-portrait.svg`, `kn/ph-landscape.svg`) dengan warna sesuai template, tanpa teks.
- Demo tetap menampilkan foto contoh melalui data demo (berlabel "Demo · data contoh fiktif").
- Tes otomatis memastikan foto contoh tidak muncul di undangan member.

## 5. Kesetiaan tampilan

- Layout, animasi, ilustrasi, dan font asli dipertahankan; perubahan hanya pada pengikatan data, keamanan, aset lokal, dan identitas.
- Tidak diklaim identik 100%: teks yang kini berasal dari data member (nama, tanggal, alamat) dapat lebih panjang/pendek dari contoh sehingga tata letak menyesuaikan; teks antarmuka template asli (mis. "Open Invitation", "Choose your character") tetap berbahasa Inggris sesuai desain.
- Token warna diterapkan lewat variabel CSS; foto, ilustrasi, dan warna kulit tidak diwarnai ulang (tanpa filter hue-rotate).

## 6. Keterbatasan yang tersisa

- T03 adalah permainan; foto hanya tampil di panel profil/cerita/galeri, tokoh tetap ilustrasi.
- T04: tokoh pada animasi adalah ilustrasi kertas; foto tampil di panel cerita & galeri.
- Pengujian lintas perangkat dilakukan dengan Chromium (emulasi ponsel 360/390 px, tablet 768 px, desktop 1366/1920 px). Safari iOS dan perangkat fisik belum diuji.
- Kinerja di ponsel kelas bawah untuk T03 (permainan) dan T04 (3D) belum diukur di perangkat nyata.
