initial commit
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
/// <reference path="../pb_data/types.d.ts" />
|
||||
//
|
||||
// M4 — API Rules for all user-scoped collections.
|
||||
//
|
||||
// CRITICAL SECURITY: without these rules, any logged-in user can read or
|
||||
// overwrite every other shop's records by passing a different `userId` in
|
||||
// the request body. The frontend cannot enforce this — it must be locked
|
||||
// down at the DB layer.
|
||||
//
|
||||
// This migration sets List/View/Create/Update/Delete rules on each
|
||||
// user-owned collection to: userId = @request.auth.id
|
||||
//
|
||||
// Notes:
|
||||
// - `users` admin-only access is NOT configured here (do that in the PB
|
||||
// admin UI under the users collection). This migration only touches the
|
||||
// per-shop data collections.
|
||||
// - `settings` is treated as user-scoped via its `userId` field (the
|
||||
// frontend stores a `businessSettings` record per user).
|
||||
// - Re-run is idempotent — applying the same rule string twice is safe.
|
||||
//
|
||||
const USER_SCOPED_COLLECTIONS = [
|
||||
'quotes',
|
||||
'repairOrders',
|
||||
'invoices',
|
||||
'appointments',
|
||||
'customers',
|
||||
'services',
|
||||
'settings',
|
||||
];
|
||||
|
||||
const RULE = 'userId = @request.auth.id';
|
||||
|
||||
migrate(
|
||||
(db) => {
|
||||
for (const name of USER_SCOPED_COLLECTIONS) {
|
||||
const col = db.findCollectionByNameOrId(name);
|
||||
if (!col) {
|
||||
console.warn(`[M4] collection "${name}" not found — skipping (create it first in admin)`);
|
||||
continue;
|
||||
}
|
||||
col.listRule = RULE;
|
||||
col.viewRule = RULE;
|
||||
col.createRule = RULE;
|
||||
col.updateRule = RULE;
|
||||
col.deleteRule = RULE;
|
||||
db.save(col);
|
||||
console.log(`[M4] applied user-scoped rules to "${name}"`);
|
||||
}
|
||||
},
|
||||
(db) => {
|
||||
// On rollback: clear the rules back to empty (full access as admin).
|
||||
// WARNING: this re-opens cross-tenant access — only run the down-migration
|
||||
// if you intend to reconfigure manually afterward.
|
||||
for (const name of USER_SCOPED_COLLECTIONS) {
|
||||
const col = db.findCollectionByNameOrId(name);
|
||||
if (!col) continue;
|
||||
col.listRule = '';
|
||||
col.viewRule = '';
|
||||
col.createRule = '';
|
||||
col.updateRule = '';
|
||||
col.deleteRule = '';
|
||||
db.save(col);
|
||||
}
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user