Initial commit from ux_aura_central
This commit is contained in:
89
firestore.rules
Normal file
89
firestore.rules
Normal file
@@ -0,0 +1,89 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user