Skip to content

chore: sincronizar cambios para uso en múltiples dispositivos#8

Closed
TeamInfinixdevcom wants to merge 1 commit into
mainfrom
pruebas
Closed

chore: sincronizar cambios para uso en múltiples dispositivos#8
TeamInfinixdevcom wants to merge 1 commit into
mainfrom
pruebas

Conversation

@TeamInfinixdevcom

Copy link
Copy Markdown
Owner

🧾 Description

This PR synchronizes recent project changes to ensure compatibility across multiple devices.

🔧 Changes

  • Updated project files for consistency
  • Synced latest configurations
  • Prepared environment for cross-device usage

✅ Notes

  • No functional changes were introduced
  • This is a maintenance update

Copilot AI review requested due to automatic review settings April 5, 2026 17:55
@gitguardian

gitguardian Bot commented Apr 5, 2026

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 4 secrets following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secrets in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
29672439 Triggered Generic CLI Secret 03e27c1 scripts/create-user-like-cristian.js View secret
29672438 Triggered Company Email Password 03e27c1 scripts/create-manuel-user.js View secret
29672441 Triggered Company Email Password 03e27c1 scripts/create-minor-user.js View secret
29672437 Triggered Generic CLI Secret 03e27c1 scripts/create-user-like-cristian.js View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secrets safely. Learn here the best practices.
  3. Revoke and rotate these secrets.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR synchronizes project changes across devices, but it also introduces several functional updates spanning UI features, Firestore security rules, Cloud Functions behavior, and administrative scripts.

Changes:

  • Added/expanded UI capabilities (lost waitlist list, richer sales filters, WhatsApp templates/pagination, model datalist + add flow).
  • Updated Firestore rules/indexes and Cloud Functions to support new/normalized fields (e.g., executiveId) and new queries.
  • Added multiple Node scripts for user creation/fixing and sales diagnostics.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
scripts/fix-active-user.js Admin script to force-create/activate a Firestore user doc.
scripts/create-user-like-cristian.js Admin SDK script to create an auth+Firestore user mirroring a source user’s permissions.
scripts/create-minor-user.js Client-SDK script to create a specific Auth+Firestore user (contains hardcoded data).
scripts/create-manuel-user.js Client-SDK script to create a specific Auth+Firestore user (contains hardcoded data).
scripts/check-january-sales.js Admin SDK script to scan monthly sales and diagnose missing fields.
public/js/waitlist-manager.js Adds “lost” status list with pagination/stats and refresh wiring.
public/js/ventas-manager.js Writes canonical executiveId and queries sales additionally by that field.
public/js/proyecciones.js More robust date parsing + forces Firestore refresh for projections.
public/js/objetivos-form.js Adjusts plan pricing display to “sin IVA” and limits mobile plan group selection.
public/js/modelos-telefonos.js Updates device model inventory list and related logging.
public/js/mis-ventas.js Adds IMEI/serie filters, improves date/category display, and adjusts state filtering.
public/js/contactacion-whatsapp.js Adds hogar plan selection from planes.json, better history pagination, and updated templates.
public/js/clients.js Adds interaction-submit reentrancy guard and null-safety improvements.
public/js/autocompletado-modelos.js Adds datalist support + UI to add custom models when missing.
public/js/auth.js Creates missing users/{uid} doc on login and refreshes tabs after role checks.
public/index.html UI layout changes: tab bar wrapping, sales filter UI, waitlist lost section, cache-busting querystrings.
public/data/users.json Adds a new user entry (currently includes PII and is publicly served).
public/data/planes.json Updates K+ plans and modifies some hogar plan prices/flags.
functions/index.js Uses executiveId when processing delivered sales + minor logging/trigger formatting tweaks.
firestore.rules Large rewrite: adds helpers, expands collections, changes ownership/role/permission model.
firestore.indexes.json Adds composite indexes for lista_espera lost queries and executiveId sales queries.
firestore-SEGURO.rules Mirrors/duplicates many of the rule changes in firestore.rules.
Comments suppressed due to low confidence (1)

public/js/mis-ventas.js:673

  • removeEventListener('change', () => this.renderVentas()) no removerá listeners previos porque se pasa una función nueva en cada llamada (distinta referencia). Esto puede acumular listeners y disparar múltiples renderizados por evento. Solución: guardar handlers como propiedades (p.ej. this._onFilterChange) y reutilizar la misma referencia en add/remove.
    [buscarPedido, buscarCedula, buscarImei, buscarSerie, filtroTipo, filtroCategoria, filtroEstado].forEach(el => {
      if (el) {
        el.removeEventListener('change', () => this.renderVentas());
        el.removeEventListener('input', () => this.renderVentas());
        el.addEventListener('change', () => { this.currentPage = 1; this.renderVentas(); });
        el.addEventListener('input', () => { this.currentPage = 1; this.renderVentas(); });
      }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +126 to +130
} catch (error) {
console.error('Error creating user:', error.message);
process.exit(1);
} finally {
process.exit(0);

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

El bloque try/catch/finally termina siempre con process.exit(0) en el finally, incluso cuando ocurre un error y se llama process.exit(1) en el catch. Esto hace que el script reporte éxito aunque haya fallado. Solución: eliminar el process.exit(0) del finally y salir con 0 solo cuando el flujo de creación realmente complete sin errores (o manejar un exitCode).

Suggested change
} catch (error) {
console.error('Error creating user:', error.message);
process.exit(1);
} finally {
process.exit(0);
process.exit(0);
} catch (error) {
console.error('Error creating user:', error.message);
process.exit(1);

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +26
const firebaseConfig = {
apiKey: "AIzaSyB_QB5AOMTRUF1tPF0ypMYwlI2F16Ugy0w",
authDomain: "executiveperformancek.firebaseapp.com",
projectId: "executiveperformancek",
storageBucket: "executiveperformancek.firebasestorage.app",
messagingSenderId: "1010572776177",
appId: "1:1010572776177:web:26432cf2220bfe11cccf50"
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);

async function createUser() {
const userData = {
name: 'Minor Sánchez Cervantes',
email: 'msanchezce@ice.go.cr',
password: 'Kolbi300',
cedula: '112570764',
role: 'executive'
};

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Este script contiene credenciales/PII en texto plano (email, cédula y especialmente password) y además usa el SDK cliente para crear usuarios. Publicar/commitear contraseñas reales es un riesgo crítico. Solución: eliminar passwords del repo (usar variables de entorno/argv), y preferir Admin SDK en scripts de backoffice; si debe existir, moverlo fuera del árbol versionado o a un ejemplo con valores ficticios.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +28
async function createUser() {
const userData = {
name: 'Manuel Escalante Leitón',
email: 'mescalanteL@ice.go.cr',
password: 'Torre1020',
cedula: '109790421',
user: 'Maesca1',
phone: '87903535',
role: 'executive'
};

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Este script contiene credenciales/PII en texto plano (email, cédula, teléfono y especialmente password). Esto no debería versionarse. Solución: retirar contraseñas/PII del código, leerlos desde variables de entorno/flags, y usar Admin SDK con cuenta de servicio (no SDK cliente) para tareas administrativas.

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +15
const serviceAccount = require('../executiveperformancek-firebase-adminsdk-fbsvc-d7042fc558.json');

admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});

const db = admin.firestore();

// Cambia este UID por el del usuario que quieres corregir
const uid = 'yF8fwbUQFpXXlOfUMyvQmHmBgNI3';

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

El script tiene un UID hardcodeado y referencia directa a un archivo de cuenta de servicio JSON. Esto es riesgoso (secreto/PII) y propenso a errores al ejecutarse en otros entornos. Solución: pasar el UID por argumento (--uid) y cargar credenciales vía GOOGLE_APPLICATION_CREDENTIALS o variables de entorno (no requerir el JSON desde el repo).

Suggested change
const serviceAccount = require('../executiveperformancek-firebase-adminsdk-fbsvc-d7042fc558.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
const db = admin.firestore();
// Cambia este UID por el del usuario que quieres corregir
const uid = 'yF8fwbUQFpXXlOfUMyvQmHmBgNI3';
admin.initializeApp();
const db = admin.firestore();
function getUidFromArgs() {
const args = process.argv.slice(2);
for (let i = 0; i < args.length; i++) {
if (args[i] === '--uid' && args[i + 1]) {
return args[i + 1];
}
if (args[i].startsWith('--uid=')) {
return args[i].slice('--uid='.length);
}
}
console.error('Uso: node scripts/fix-active-user.js --uid <USER_UID>');
console.error('Asegúrate también de configurar GOOGLE_APPLICATION_CREDENTIALS o credenciales de aplicación por entorno.');
process.exit(1);
}
const uid = getUidFromArgs();

Copilot uses AI. Check for mistakes.
Comment thread public/data/users.json
Comment on lines +88 to +99
{
"id": "lMOh5PUYFHSNGKBj6QaGqrFdhjv1",
"uid": "lMOh5PUYFHSNGKBj6QaGqrFdhjv1",
"name": "Manuel Escalante Leitón",
"email": "mescalanteL@ice.go.cr",
"cedula": "109790421",
"user": "Maesca1",
"phone": "87903535",
"role": "executive",
"isActive": true,
"createdAt": "2026-02-04T00:00:00.000Z",
"createdBy": "script"

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public/data/users.json está en una ruta pública y contiene PII (UID, cédula, teléfono, email). Esto quedaría expuesto a cualquier cliente web. Solución: remover este registro del bundle público o mover estos datos a un backend/Firestore con reglas; si es solo para desarrollo, sacarlo de public/ y del control de versiones.

Copilot uses AI. Check for mistakes.
Comment thread public/data/planes.json
{ "id": "duotelint500mbps", "nombre": "Dúo Telefonía + Internet 500 Mbps", "precio": 30318 },
{ "id": "duotelint800mbps", "nombre": "Dúo Telefonía + Internet 800 Mbps", "precio": 130458 },
{ "id": "duotelint1gbps", "nombre": "Dúo Telefonía + Internet 1 Gbps", "precio": 161046 }
{ "id": "duotelint100mbps", "nombre": "Dúo Telefonía + Internet 100| Mbps", "precio": 15948 },

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

El nombre del plan incluye un carácter | ("Internet 100| Mbps"), que probablemente es un typo y afectará la UI/búsqueda/plantillas. Solución: corregir el string a "Internet 100 Mbps".

Suggested change
{ "id": "duotelint100mbps", "nombre": "Dúo Telefonía + Internet 100| Mbps", "precio": 15948 },
{ "id": "duotelint100mbps", "nombre": "Dúo Telefonía + Internet 100 Mbps", "precio": 15948 },

Copilot uses AI. Check for mistakes.
Comment thread public/js/auth.js
Comment on lines +169 to +180
// Si el documento no existe, crearlo con datos básicos
console.log('📝 Documento de usuario no existe, creando...');
userData = {
email: user.email,
name: user.displayName || 'Usuario',
isActive: true,
role: 'user',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
await setDoc(doc(db, 'users', user.uid), userData);
console.log('✅ Documento de usuario creado exitosamente');

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

El PR description indica "No functional changes", pero aquí se están introduciendo cambios funcionales relevantes (p.ej. creación automática del documento users/{uid} en login y cambios de acceso/roles). Solución: actualizar la descripción del PR para reflejar estos cambios, o separar los cambios funcionales en otro PR.

Copilot uses AI. Check for mistakes.
Comment thread public/js/auth.js
Comment on lines +169 to +180
// Si el documento no existe, crearlo con datos básicos
console.log('📝 Documento de usuario no existe, creando...');
userData = {
email: user.email,
name: user.displayName || 'Usuario',
isActive: true,
role: 'user',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
await setDoc(doc(db, 'users', user.uid), userData);
console.log('✅ Documento de usuario creado exitosamente');

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

En el login, si el documento de usuario no existe se crea con isActive: true automáticamente. Esto elimina la posibilidad de un flujo de aprobación/alta controlada y, combinado con reglas permisivas, puede abrir acceso a usuarios no previstos. Solución: crear el doc con isActive: false y mostrar un mensaje de "pendiente de activación", o mover la creación/activación a una Cloud Function/admin workflow.

Suggested change
// Si el documento no existe, crearlo con datos básicos
console.log('📝 Documento de usuario no existe, creando...');
userData = {
email: user.email,
name: user.displayName || 'Usuario',
isActive: true,
role: 'user',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
await setDoc(doc(db, 'users', user.uid), userData);
console.log('✅ Documento de usuario creado exitosamente');
// Si el documento no existe, crearlo en estado pendiente de activación
console.log('📝 Documento de usuario no existe, creando en estado pendiente...');
userData = {
email: user.email,
name: user.displayName || 'Usuario',
isActive: false,
role: 'user',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
await setDoc(doc(db, 'users', user.uid), userData);
console.log('✅ Documento de usuario creado exitosamente en estado inactivo');
showMessage('⏳ Tu cuenta está pendiente de activación. Contacta a un administrador.', 'error');
await signOut(auth);
return;

Copilot uses AI. Check for mistakes.
Comment thread firestore.rules
Comment on lines +27 to 31
match /lista_espera/{itemId} {
allow read, create, update: if isSignedIn() && isActiveUser();
allow delete: if isAdmin();
allow read, write: if isAdmin();
}

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

La UI (WaitlistManager) permite eliminar ítems de lista_espera mediante deleteDoc, pero aquí delete está permitido solo para admins. Esto causará fallos para ejecutivos normales al intentar borrar. Solución: permitir delete al dueño (resource.data.userId == request.auth.uid) o esconder/deshabilitar la acción de eliminar para no-admins.

Copilot uses AI. Check for mistakes.
Comment thread firestore-SEGURO.rules
// ============================================
match /lista_espera/{itemId} {
allow read, create, update: if isSignedIn() && isActiveUser();
allow delete: if isAdmin();

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

La UI permite eliminar ítems de lista_espera, pero las reglas dejan delete solo para admins. Esto provocará errores en producción para usuarios no admin. Solución: permitir delete al owner (resource.data.userId == request.auth.uid) o ajustar la UI para que solo admins vean la acción.

Suggested change
allow delete: if isAdmin();
allow delete: if isAdmin() || (isSignedIn() && resource.data.userId == request.auth.uid);

Copilot uses AI. Check for mistakes.
@TeamInfinixdevcom

Copy link
Copy Markdown
Owner Author

se cierra porque se eliminan los scripts erroneos

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants