From 39adcc21ee3ca5f451690eb5c3e030f6b48c3329 Mon Sep 17 00:00:00 2001 From: cygouw Date: Thu, 4 Jun 2026 23:06:53 +0700 Subject: [PATCH] feat(staff): protect WhatsApp links from basic web scraping --- groups/C4A/js/ui.js | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/groups/C4A/js/ui.js b/groups/C4A/js/ui.js index 193ed38..5984123 100644 --- a/groups/C4A/js/ui.js +++ b/groups/C4A/js/ui.js @@ -36,6 +36,29 @@ function isValidWhatsAppNumber(phone) { return norm.startsWith('628') && norm.length >= 10 && norm.length <= 15; } +/** + * Enkripsi nomor telepon menggunakan Base64 untuk keamanan kontak. + * @param {string} phone - Nomor telepon ternormalisasi + * @returns {string} Nomor telepon terenkripsi Base64 + */ +function encodePhone(phone) { + return btoa(normalizePhone(phone)); +} + +/** + * Dekripsi nomor telepon dari Base64. + * @param {string} encoded - Nomor telepon terenkripsi Base64 + * @returns {string} Nomor telepon terdekripsi + */ +function decodePhone(encoded) { + try { + return atob(encoded); + } catch (error) { + console.error('Gagal mendekripsi nomor telepon:', error); + return ''; + } +} + /** * Merender daftar staf pendukung ke dalam container HTML. * @param {Array} staffs - Array data staf pendukung @@ -58,6 +81,7 @@ export function renderStaffCards(staffs) { image, location, phone, + contact_consent: contactConsent, schedule, tasks } = staff; @@ -70,6 +94,11 @@ export function renderStaffCards(staffs) { ).join(''); const tasksHTML = tasks.map(task => `
  • ${task}
  • `).join(''); + const isPhoneValid = isValidWhatsAppNumber(phone); + const encodedPhone = isPhoneValid ? encodePhone(phone) : ''; + const displayPhone = isPhoneValid ? formatPhoneForDisplay(phone) : '-'; + const hideContactItemClass = contactConsent ? '' : 'is-hidden'; + const hideContactActionClass = (contactConsent && isPhoneValid) ? '' : 'is-hidden'; const initial = name ? name.charAt(0).toUpperCase() : ''; const card = document.createElement('div'); @@ -96,15 +125,29 @@ export function renderStaffCards(staffs) {
    ${scheduleHTML}
    -
    📞
    Kontak${phone}
    +
    📞
    Kontak WhatsApp${displayPhone}
    Tugas & Tanggung Jawab
    +
    + +
    `; container.appendChild(card); + + // Setup WA button click handler dengan dekrips nomor + const waBtn = card.querySelector('[data-wa]'); + if (waBtn) { + waBtn.addEventListener('click', () => { + const phoneNum = decodePhone(waBtn.dataset.wa); + if (phoneNum) { + window.open(`https://wa.me/${phoneNum}`, '_blank', 'noopener,noreferrer'); + } + }); + } }); } // ============================================================