firebaseextended / user-data-protection Goto Github PK
View Code? Open in Web Editor NEWGeneralizable examples of protecting user data in Firebase Applications
License: Apache License 2.0
Generalizable examples of protecting user data in Firebase Applications
License: Apache License 2.0
@return {arrau}
sould be @return {array}
An example of a wipout_config.json file would be helpful.
throw new Error('Not a valid conjunction list, can\'t initialize');
{
"rules": {
"nofailure": {
"uid": {
".write": "auth.uid === newData.val()"
}
},
"failure2": {
".write": "auth.uid === newData.child('uid').val()"
},
}
}
Given the database rules below, we generated rules that contained $
, which caused an error when the function ran. The rules are complicated enough that we might want to gracefully degrade.
Database rules:
{
"rules": {
"feed": {
"$uid": {
".read": "auth.uid === $uid",
".write": "auth.uid === $uid",
"$postId": {
".validate": "newData.val() === true && newData.parent().parent().parent().child('posts').child($postId).exists()"
}
}
},
"posts": {
".read": true,
"$postId": {
".write": "!data.exists() || data.exists() && auth.uid === data.child('author').child('uid').val()", // Allow new writes and allow updates and deletes to own posts.
"author": {
"uid": {
".validate": "auth.uid === newData.val()"
}
}
}
},
"comments": {
".read": true,
"$postId": {
".write": "!newData.exists() && auth.uid === root.child('posts').child($postId).child('author').child('uid').val() && !newData.parent().parent().child('posts').child($postId).exists()", // Allow deletes from the post owner
".validate": "root.child('posts').child($postId).exists()", // Check that the post exists
"$commentId": {
".write": "!data.exists() || data.exists() && auth.uid === data.child('author').child('uid').val()", // Can write new comments and edit/delete particular comment if you are the author.
"author": {
"uid": {
".validate": "auth.uid === newData.val()"
}
}
}
}
},
"likes": {
".read": true,
"$postId": {
".write": "!newData.exists() && auth.uid === root.child('posts').child($postId).child('author').child('uid').val() && !newData.parent().parent().child('posts').child($postId).exists()", // Allow deletes from the post owner
".validate": "root.child('posts').child($postId).exists()", // Check that the post exists
"$uid": {
".write": "auth.uid === $uid",
".validate": "newData.val() === now"
}
}
},
"followers": {
".read": true,
"$followedUid": {
"$followerUid": {
".write": "auth.uid === $followerUid", // Can only add yourself as a follower
".validate": "newData.val() === true && newData.parent().parent().parent().child('people').child($followerUid).child('following').child($followedUid).exists()" // Makes sure /people/.../following is in sync
}
}
},
"people": {
".indexOn": ["_search_index/full_name", "_search_index/reversed_full_name"],
".read": true,
"$uid": {
".write": "auth.uid === $uid",
"full_name": {
".validate": "newData.isString()"
},
"profile_picture": {
".validate": "newData.isString()"
},
"posts": {
"$postId": {
".validate": "newData.val() === true && newData.parent().parent().parent().parent().child('posts').child($postId).exists()"
}
},
"_search_index": {
"full_name": {
".validate": "newData.isString()"
},
"reversed_full_name": {
".validate": "newData.isString()"
}
},
"following": {
"$followedUid": {
".validate": "newData.parent().parent().parent().parent().child('followers').child($followedUid).child($uid).val() === true" // Makes sure /followers is in sync
}
}
}
},
"$other": {
".validate": false
}
}
}
Generated wipeout rules:
{ "path": "/feed/#WIPEOUT_UID" }
{ "except": "/comments/$postId/$commentId", "path": "/comments/$postId" }
{ "except": "/likes/$postId/$uid", "path": "/likes/$postId" }
{ "path": "/people/#WIPEOUT_UID" }
{ "path": "/followers/$followedUid/#WIPEOUT_UID" }
Error from running the function:
Error: Firebase.child failed: First argument was an invalid path: "comments/$postId". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]" at Error (native) at Ge (/user_code/node_modules/firebase-admin/lib/database/database.js:111:59) at R.h.n (/user_code/node_modules/firebase-admin/lib/database/database.js:243:178) at Fd.h.gf (/user_code/node_modules/firebase-admin/lib/database/database.js:91:631) at evalSingleExcept (/user_code/wipeout.js:219:30) at evalExcepts (/user_code/wipeout.js:266:23) at Promise.all.then.then.then.then (/user_code/wipeout.js:585:24) at process._tickDomainCallback (internal/process/next_tick.js:135:7)
--
Came here too look for best practices for separate files with cloud functions and saw this line: https://github.com/firebase/user-data-protection/blob/707667aaab119ec9b865c306cccb42990c5cded1/functions/wipeout.js#L597
Maybe I am misunderstanding the reason (something with scoping?), but couldn't the cloud function itself be what you exported? Instead of an anonymous function that returns the function (it doesn't seem to be called with bind
or other context passing methods).
Then in index.js instead you could do the following:
// exports.cleanupUserData = wipeout.cleanupUserData(); // <-- replace this
exports.cleanupUserData = wipeout.cleanupUserData // with this
Its what I have been doing when run cloud functions in separate files, but wasn't sure if there was a downside to doing things this way.
Either way, the reason for the issue - If there is a reason things are done this way, maybe it is worth a comment. Thanks for the example.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.