I'm trying to develop a payment with checkout (using paypal) to get the paid plan of a discord bot. Then, when the user pays, the child "prem" is set to true, like so:
paypal.Buttons({
style: {
color: 'blue',
shape: 'pill'
},
createOrder:function (data, actions){
return actions.order.create({
purchase_units: [{
amount:{
value: '1.00'
}
}]
});
},
onApprove:function (data, actions){
return actions.order.capture().then(function (details){
console.log(details)
database.ref('server/' + guildId + '/prem').set(true); //here
})
}
}).render('#paypal-payment-button');
The problem is that my real time db has no security rules (it accepts all requests):
{
"rules": {
".read": true,
".write": true,
}
}
This is my db structure:
{
"server": {
"858941532694118431": {
"prem": true, //premium plan activated
"settings": {
"error": "on",
"warnings": "on"
}
}
}
}
Since my rules give access to everyone, each user could write this in the console to activate the premium without paying:
database.ref('server/' + serverId + '/prem').set(true);
How could I set up my security rules so that no user can modify that child but only the automatic system can? There's a way?
You should not be allowing users to update the prem
at first place. Even if you allow users to update their own membership, they can still turn it to true
without Paypal payment.
Instead, try using Paypal Webhooks which can trigger a HTTP Cloud function whenever a payment is received and change user's premium status from the Cloud function after validating the payment.
However, even if you wanted to write to database directly, the server ID doesn't seem to be default Firebase Auth UID. If that's not user's UID then it'll be difficult to implement rules for it.
{
"rules": {
"server": {
"$uid": {
".write": "$uid === auth.uid"
}
}
}
}
These rules will allow a user with UID 1234
to edit /server/1234/
path only.
Since the ID is Discord guild's ID, then it'll be best to use a webhook. You can use Firebase Cloud Function and set it's URL as webhook delivery URL in Paypal. The webhook should contain additional information about the transaction and you can even some metadata like guild ID if necessary. Validate the payment and update your database as required.
Make sure the rules are set to ".write": false
so no user can directly update that status.