Git Product home page Git Product logo

user-data-protection's People

Contributors

rachelmyers avatar samtstern avatar vikrum avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

user-data-protection's Issues

Failure on simple expression

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()"
    },
  }
}

Generated wipeout rule contained special characters and caused errors

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)
--

comment about why exporting an anonymous function is necessary

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.