Files
ux_aura_assistant/firestore.rules
2026-03-25 01:21:37 +05:30

90 lines
3.0 KiB
Plaintext

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// ===============================================================
// Assumed Data Model
// ===============================================================
//
// Collection: users
// Document ID: {uid} (Firebase Auth UID)
// Fields:
// - name: string (required, 1-100 chars)
// - email: string (required, valid email format)
// - phone: string (required, 1-20 chars)
// - uid: string (required, matches document ID)
// - createdAt: string (required, ISO 8601 format)
//
// Collection: subscriptions
// Document ID: {uid} (Firebase Auth UID)
// Fields:
// - plan: string (required, enum: ['Aura Pro'])
// - topUpAmount: number (required, positive)
// - rechargeLevel: number (required, positive)
// - uid: string (required, matches document ID)
// - updatedAt: string (required, ISO 8601 format)
//
// ===============================================================
// ===============================================================
// Helper Functions
// ===============================================================
function isAuthenticated() {
return request.auth != null;
}
function isOwner(userId) {
return isAuthenticated() && request.auth.uid == userId;
}
function isValidEmail(email) {
return email is string && email.matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
}
function isValidDateString(dateStr) {
return dateStr is string && dateStr.matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}.*Z?$");
}
function hasOnlyAllowedFields(fields) {
return request.resource.data.keys().hasOnly(fields);
}
// Domain Validators
function isValidUser(data) {
return hasOnlyAllowedFields(['name', 'email', 'phone', 'uid', 'createdAt']) &&
data.name is string && data.name.size() > 0 && data.name.size() <= 100 &&
isValidEmail(data.email) &&
data.phone is string && data.phone.size() > 0 && data.phone.size() <= 20 &&
data.uid == request.auth.uid &&
isValidDateString(data.createdAt);
}
function isValidSubscription(data) {
return hasOnlyAllowedFields(['plan', 'topUpAmount', 'rechargeLevel', 'uid', 'updatedAt']) &&
data.plan in ['Aura Pro'] &&
data.topUpAmount is number && data.topUpAmount > 0 &&
data.rechargeLevel is number && data.rechargeLevel >= 0 &&
data.uid == request.auth.uid &&
isValidDateString(data.updatedAt);
}
// ===============================================================
// Rules
// ===============================================================
match /users/{uid} {
allow read, write: if true;
}
match /subscriptions/{uid} {
allow read, write: if true;
}
// Default deny
match /{path=**} {
allow read, write: if false;
}
}
}