Meteor. Prevent multiple inserts from console - javascript

Let's imagine I'm a bad man, and I see that website uses Meteor.
I search for a collection description in js files (let it be "Posts"), and write in console
for (var i = 0; i < 10000000000; i++) {
Posts.insert({title:'foobar'});
}
And we got the DB full of trash.
How to prevent this? Registration isn't much problem for such attack, I suppose.

Use the allow rules.
First remove the insecure package:
meteor remove insecure
Then make some rules (e.g you have to be logged in) & in the example below you can only modify your own documents.
Server side code
Posts.allow({
insert: function (userId, doc) {
// the user must be logged in, and the document must be owned by the user
return (userId && doc.owner === userId);
},
update: function (userId, doc, fields, modifier) {
// can only change your own documents
return doc.owner === userId;
},
remove: function (userId, doc) {
// can only remove your own documents
return doc.owner === userId;
}
});

Related

(MongoDB) Data submitted from user A is being sent into User B's document

https://imgur.com/a/giK2bSt
I'm finding and updating the current user's document in the db using:
Player.findOneAndUpdate(
player.discordID (example below), but it ignores the discordID query and inputs the data into the wrong document. I logged the currrent user's discordID in the terminal to make sure it is fetching the current user's and it is.
if (
// if user submitted data matches the gamertags and platforms listed in-
// their call of duty account, execute assignRoleNow
(loggedIn =
true &&
checkTag == true &&
checkPlat == true)
) {
console.log(player.discordID);
console.log(player);
Player.findOneAndUpdate(
player.discordID,
{
$set: {
platform: platform,
gamertag: gamertag,
},
},
function callback(err, doc) {
if (err) {
// Show errors
console.log(err);
}
}
);
The query portion of you findOneAndUpdate may not be in the correct format. Remember, it should look the same as a find for the Player so it may need to be:
{discordId: player.discordID}
instead of just:
player.discordID

Firestore Delete All References of A User

I have a chat app build in react native. When a user decides to delete their profile, I want to remove all references of them from the database.
The DB has references to their user id in the "matches" table, the "chat" table, and the "messages" table for each of the people the deleted user was chatting with.
I am using firebase functions to handle the deletion of the user doc data and auth but I am not sure what the best way to go about removing all of these references would be. My question is: what is the best way to remove all references of an ID out of a somewhat complex database? I assume this will be taxing to loop through every single user in the DB to search for this one ID.
deleteAccount = () => {
var db = firebase.firestore();
firebase.auth().onAuthStateChanged(async (user) => {
if (user) {
//delete user data
db.collection("Users")
.doc(user.uid)
.delete();
} else {
console.log("user needs to reauth");
return false;
}
});
};
firebase functions
exports.deleteUser = functions.firestore
.document("Users/{userID}")
.onDelete((snap, context) => {
const deletedValue = snap.data();
// Delete the images
try {
admin.auth().deleteUser(deletedValue.id);
const imgRef1 = firebase.storage().ref(user.uid + "/images/0")
? firebase.storage().ref(user.uid + "/images/0")
: null;
const imgRef2 = firebase.storage().ref(user.uid + "/images/1")
? firebase.storage().ref(user.uid + "/images/1")
: null;
const imgRef3 = firebase.storage().ref(user.uid + "/images/2")
? firebase.storage().ref(user.uid + "/images/2")
: null;
imgRef1.delete().then(function() {
imgRef2.delete().then(function() {
imgRef3.delete().then(function() {});
});
});
} catch (e) {
console.log("no images to delete");
}
});
Firebase products such as the databases and storage have no implicit knowledge of what data belongs to what user. That relation only exists because your application code made it.
For that reason you will also have to look up/traverse the relations when deleting the user, to find (and delete) their data. There are no shortcuts in the product here, although there is a open-source library that contains an implementation that works from a configuration file: user-data-protection
Edit: I just realized there's actually an Extension to Delete User Data, which does pretty much the same as the library linked above. It might be worth to have a look if that suits your needs

Firebase checking two different database refs despite a if check

I am trying to seperate two different logins for the different types of users that are in the account. One of the users is a regular consumer who is able to search through the app. The other is a business dashboard where businesses get to see what users are checkedin to their business.
The problem is that when I check my two different database references, it seems it checks both of them instead of validating the first check and proceeds to pull and error saying one of my nodes is null.
The case it apprently fails is the first if check but in my database the node userType is set properly:
The problem seems to be it auth().onStateChanged where it looks for the uid of in both database references. When I try to login with a business account it successfully enters that statement and redirects, when I log in with a consumer account it tries to check the business refs if and then pulls out the error userType is null cannot read
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// This prompts the user to allow for location access
// When logged in it would allow us to show the
// nearby businesses to the user
var uid = user.uid
if(window.navigator.geolocation) {
window.navigator.geolocation.getCurrentPosition(function(position){
})
}
var uid = user.uid
console.log(uid)
business.child(uid).on("value", snap => {
if(snap.val().userType == "business") {
alert("This is not a consumer account!")
firebase.auth().signOut()
window.location.href = "businesslogin.html"
} else {
consumer.child(uid).on("value", snap => {
if(snap.val().userType == "consumer") {
if(snap.val().isPhoneVerified == true) {
window.location.href = 'nearbyBusinesses.html'
} else {
window.location.href = 'loginVerification.html'
}
if(snap.val().isUserCheckedin == true){
window.location.href = "leave.html" + '#' + snap.val().checkedInBusinessId
} else {
window.location.href = "nearbyBusinesses.html"
}
}
})
}
})
}
})
The bug is in this line if(snap.val() == "business"). It needs to be if(snap.val().userType == "business"). Atleast that is what i can see imediately. Try that and see if it solves your problem

How to remove logged in user in Meteor

I'm developing an app in Meteor and I want to know how I do can delete a user's account who is logged into the system? I mean that you can delete your account (like Tinder or Facebook) and the application ejects you because you're already deleted, and you no longer exist.
With a simple button of "Delete your account" attached.
If you could help me; I'm still a novice I'd really appreciate it, I try to retrieve the id of the current user with Meteor.userId(), and I was creating a method in the following way:
Meteor.methods({
SuprimirPersona: function(id) {
var postId = Meteor.userId();
const userId = this.userId;
const p = Meteor.users.findOne(postId);
if (userId && p === userId) {
Meteor.users.remove({
postId: this._id
},
function(error, result) {
if (error) {
console.log("Error removing user:", error);
} else {
console.log("users removed:" + result);
}
})
}
}
});
And calling the method in the following way but it does not give any results, I do not understand why:
'click #Desactivarr': function() {
var postId = Meteor.userId();
Meteor.call('SuprimirPersona', userId, function(error, result) {
if (error) {
console.log("Somee Error");
}
});
Meteor.logout(function() {
FlowRouter.go('/');
});
},
Hope someone could help me! Regards!
I've just answered this question on Meteor Forums:
https://forums.meteor.com/t/how-to-remove-logged-in-user-in-meteor/42639/3
The issue is you're trying to remove Users by postId, instead of Users.remove({_id: id}). You're removing nothing :)
To remove a user from the user's collection. You need to get the userid of the user you want to remove. This you can get by calling Meteor.userId() on the client to get the userid of the user or this.userId on the server. You need to logout the user and after a successful logout you can pass the userid you got to the meteor.users.remove(userId)
You are doing some unnecessary things on the client and server side - like getting the same user id multiple times, not even passing it to the server side method and then getting it again.
I think what you are trying to do is get the id of a user that posted something and pass it to the server side, where you check if the poster's id is the same as the id of the current user. If so, you remove the user, otherwise nothing happens.
'click #desactivarr' : function() {
var postID = <get the id of the user you want to delete here>;
Meteor.call("suprimirPersona", postID, callbackfunc);
}
Then on the server side it would be
Meteor.methods({
suprimirPersona : function(postID) {
var userID = Meteor.userId();
if (userID && postID === userID) {
Meteor.users.remove({ postId : userID })
}
}
});
Meteor.userId() and this.userId return the id of the currently logged in user that is executing the code on the client side or making the request to a server side method.

Writing a function to adapt for two different cases?

Maybe I am not thinking hard enough but lets say I have code that is 99% similar what would be the most minimal way of building a function for it?
// this is just an express route, not the function I am building
// doPay() is the function I am trying to build properly
function(req,res) {
if(req.user) {
// I can use req.user.id in my function
doPay(req,res);
} else {
passport.authenticate('local-signup', function(err, user, info) {
// instead of req.user.id I would just need user.id
doPay();
});
}
}
doPay()
// My doPay() function, above I need to pass either req.user.id or user.id
// based on the boolean, so how do I adjust this to adapt to that?
gateway.customer.find(req.user.id, function(err, customer) {
//do payment stuff for an existing user, if the user is new I need to use
//user.id above
});
Here are two alternate designs.
You could make the function take 3 parameters
function doPay(req, res, user)
and then test in that function to select what is available
var userId;
if (req && req.user && req.user.id) userId = req.user.id;
if (!userId && user && user.id) userId = user.id;
if (!userId) throw "error...";
or you could choose to make the 3rd parameter the userId to use
function doPay(req,res,userId)
and put the userId source logic in the routing code instead of the doPay code. The doPay would just use the userId it was told to use. I think this design is what #Bergi was suggesting in the first comment.

Categories