'use strict' const { log } = require('./helpers') const erp = require('./erp') const { otpEmailHtml } = require('./email-templates') const otpStore = new Map() function generateOTP () { return String(Math.floor(100000 + Math.random() * 900000)) } async function sendOTP (identifier) { const isEmail = identifier.includes('@') const code = generateOTP() const expires = Date.now() + 10 * 60 * 1000 let customer = null if (isEmail) { const rows = await erp.list('Customer', { fields: ['name', 'customer_name', 'cell_phone', 'email_id'], filters: [['email_id', '=', identifier]], limit: 1, }) if (rows.length) customer = rows[0] } else { const { lookupCustomerByPhone } = require('./helpers') customer = await lookupCustomerByPhone(identifier) } if (!customer) return { found: false } otpStore.set(identifier, { code, expires, customerId: customer.name, customerName: customer.customer_name }) if (isEmail) { const { sendEmail } = require('./email') await sendEmail({ to: identifier, subject: 'Code de vérification Gigafibre', html: otpEmailHtml(code), }) } else { try { const { sendSmsInternal } = require('./twilio') await sendSmsInternal(identifier, `Gigafibre — Votre code de vérification : ${code}\nExpire dans 10 min.`) } catch (e) { log('OTP SMS failed:', e.message) } } log(`OTP sent to ${identifier} for customer ${customer.name}`) return { found: true, sent: true, channel: isEmail ? 'email' : 'sms' } } async function verifyOTP (identifier, code) { const entry = otpStore.get(identifier) if (!entry) return { valid: false, reason: 'no_otp' } if (Date.now() > entry.expires) { otpStore.delete(identifier); return { valid: false, reason: 'expired' } } if (entry.code !== code) return { valid: false, reason: 'wrong_code' } otpStore.delete(identifier) const result = { valid: true, customer_id: entry.customerId, customer_name: entry.customerName } try { const c = await erp.get('Customer', entry.customerId, { fields: ['name', 'customer_name', 'cell_phone', 'email_id', 'tel_home'], }) if (c) { result.phone = c.cell_phone || c.tel_home || '' result.email = c.email_id || '' } if (!result.email) { try { const contacts = await erp.list('Contact', { fields: ['email_id'], filters: [['Dynamic Link', 'link_doctype', '=', 'Customer'], ['Dynamic Link', 'link_name', '=', entry.customerId]], limit: 1, }) if (contacts[0]?.email_id) result.email = contacts[0].email_id } catch (e) { log('OTP - Contact email fallback error:', e.message) } } const locs = await erp.list('Service Location', { fields: ['name', 'address_line', 'city', 'postal_code', 'location_name', 'latitude', 'longitude'], filters: [['customer', '=', entry.customerId]], limit: 20, }) if (locs.length) { result.addresses = locs.map(l => ({ name: l.name, address: l.address_line || l.location_name || l.name, city: l.city || '', postal_code: l.postal_code || '', latitude: l.latitude || null, longitude: l.longitude || null, })) } } catch (e) { log('OTP verify - customer details fetch error:', e.message) } return result } module.exports = { otpStore, generateOTP, sendOTP, verifyOTP }