CopyBee Icon UNIT // 02 • AMBER SECTOR

CopyBee

Depósito y difusor instantáneo de configuraciones seguras. Copia con un solo clic el conjunto canónico de reglas de seguridad de Firestore (RBAC, propietarios y bloqueo total administrativo) listas para producción.

//

firestore.rules

Reglas predefinidas con modelo RBAC, protección de colecciones privadas y bloqueo administrativo.

CANONICAL // FIRESTORE_SECURITY_SPEC_V2
RULES_VERSION = '2'
rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    
    // ===============================================================
    // FUNCIONES AUXILIARES DE SEGURIDAD (RBAC Y PROPIEDAD)
    // ===============================================================

    function isAuthenticated() {
      return request.auth != null;
    }

    // Comprueba si el usuario tiene custom claims de admin o rol 'admin' en su documento de usuario
    function isAdmin() {
      return isAuthenticated() && (
        request.auth.token.admin == true ||
        (exists(/databases/$(database)/documents/users/$(request.auth.uid)) &&
         get(/databases/$(database)/documents/users/$(request.auth.uid)).data.get('role', '') == 'admin')
      );
    }

    function isOwner(userId) {
      return isAuthenticated() && request.auth.uid == userId;
    }

    // ===============================================================
    // REGLAS ESPECÍFICAS POR COLECCIÓN
    // ===============================================================

    // 0. CLAVES SECRETAS DE ACCESO ADMINISTRATIVO
    // Bloqueo total desde el cliente/navegador. 
    // Solo accesible por el servidor backend (Firebase Admin SDK).
    match /claves/{docId} {
      allow read, write: if false;
    }
    match /clavesadmin/{docId} {
      allow read, write: if false;
    }

    // 1. USUARIOS Y SU INFORMACIÓN PRIVADA
    match /users/{userId} {
      allow read: if isOwner(userId) || isAdmin();
      // Un usuario solo puede registrarse a sí mismo y no puede auto-asignarse rol admin
      allow create: if isOwner(userId) && request.resource.data.get('role', 'user') != 'admin';
      // Puede actualizar sus datos personales pero no auto-escalar privilegios a admin
      allow update: if (isOwner(userId) && request.resource.data.get('role', 'user') == resource.data.get('role', 'user')) || isAdmin();
      allow delete: if isAdmin();
      
      // Subcolecciones privadas del usuario (carrito, direcciones, métodos de pago, favoritos)
      match /cartItems/{itemId} {
        allow read, write: if isOwner(userId) || isAdmin();
      }
      match /addresses/{addressId} {
        allow read, write: if isOwner(userId) || isAdmin();
      }
      match /paymentMethods/{methodId} {
        allow read, write: if isOwner(userId) || isAdmin();
      }
      match /wishlist/{itemId} {
        allow read, write: if isOwner(userId) || isAdmin();
      }
    }

    // 2. PRODUCTOS Y VARIANTES
    match /products/{productId} {
      // Lectura pública para cualquier visitante de la tienda
      allow read: if true;
      // Modificaciones y gestión de catálogo restringidas al administrador
      allow write: if isAdmin();

      match /variants/{variantId} {
        allow read: if true;
        allow write: if isAdmin();
      }
      
      // Reseñas de productos
      match /reviews/{reviewId} {
        allow read: if true;
        allow create: if isAuthenticated();
        allow update, delete: if isAdmin();
      }
    }

    // 3. CATEGORÍAS
    match /categories/{categoryId} {
      allow read: if true;
      allow write: if isAdmin();
    }

    // 4. TRADUCCIONES E IDIOMAS (i18n)
    match /translations/{translationId} {
      allow read: if true;
      allow write: if isAdmin();
    }

    // 5. PEDIDOS (ORDERS)
    match /orders/{orderId} {
      // El cliente solo puede leer sus propios pedidos; el administrador puede ver todos
      allow read: if isAdmin() || (isAuthenticated() && resource.data.uid == request.auth.uid);
      allow create: if isAuthenticated() && request.resource.data.uid == request.auth.uid;
      allow update, delete: if isAdmin();
    }

    // 6. CÓDIGOS DE PROMOCIÓN Y DESCUENTOS
    match /promotions/{promoId} {
      allow read: if true;
      allow write: if isAdmin();
    }

    // 7. AJUSTES GLOBALES Y CONFIGURACIÓN DE LA TIENDA
    match /settings/{settingId} {
      allow read: if true;
      allow write: if isAdmin();
    }

    // 8. PÁGINAS CMS DEL EDITOR VISUAL (home, about, catalog)
    match /pages/{pageId} {
      allow read: if true;
      allow write: if isAdmin();
    }

    // ===============================================================
    // BLOQUEO POR DEFECTO PARA CUALQUIER OTRA RUTA
    // ===============================================================
    match /{document=**} {
      allow read, write: if false;
    }
  }
}