Skip to content

Instantly share code, notes, and snippets.

@alan89
Forked from torresalmonte/index.js
Created December 27, 2019 17:42
Show Gist options
  • Save alan89/1725860df7a0d28cc7732eae4894741b to your computer and use it in GitHub Desktop.
Save alan89/1725860df7a0d28cc7732eae4894741b to your computer and use it in GitHub Desktop.
Script to delete Storage rulesets using the "firebaserules" REST API
const admin = require('firebase-admin');
const {sleep} = require('sleep');
// asumes the existance of the GOOGLE_APPLICATION_CREDENCIAL env variable
const firebaseApp = admin.initializeApp();
async function getRulesets(projectId, firebaseApp, pageToken) {
pageToken = pageToken || '';
let token = await firebaseApp.options.credential.getAccessToken();
let accessToken = token.access_token;
let url = `https://firebaserules.googleapis.com/v1/projects/${projectId}/rulesets?pageToken=${pageToken}`;
const request = {
url: url,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`
},
method: 'GET'
};
let response = null;
try {
response = await firebaseApp.options.credential.credential_.httpClient.send(request);
} catch (err) {
console.error(err);
}
rules = response ? response.parsedData : {};
return rules;
} // getRulesets
/**
*
* @param {Firebase App instance} firebaseApp
* @param {Ruleset name, as received in the JSON response} rulesetName
*/
async function deleteRuleset(firebaseApp, rulesetName) {
if (!firebaseApp || !rulesetName) {
throw new Exception("firebaseApp and ruleset name required");
}
let token = await firebaseApp.options.credential.getAccessToken();
let accessToken = token.access_token;
let url = `https://firebaserules.googleapis.com/v1/${rulesetName}`;
const request = {
url: url,
headers: {
'Authorization': `Bearer ${accessToken}`
}
};
let response = null;
try {
let result = await firebaseApp.options.credential.credential_.httpClient.send(request);
response = result.parsedData;
} catch (err) {
console.error(err);
}
return response;
} // deleteRuleset
// WARNING: deleting storage rulesets
// make sure to backup the current ruleset
(async () => {
// NOTE: set the Firebase projectId
const projectId = "YOUR_PROJECT_ID";
let pageToken = null;
let pageCounter = 0;
let rulesCounter = 0;
while (true) {
// skip Firestore rulesets
let rules = await getRulesets(projectId, firebaseApp, pageToken);
if (rules.rulesets) {
pageCounter++;
for (let ruleset of rules.rulesets) {
//console.log(ruleset);
// we just remove the Storage rulesets
if (ruleset.metadata.services == 'firebase.storage') {
// we keep the first entry
if (rulesCounter > 0) {
console.log(`DELETING ${ruleset.name}`);
// WARNING: the following line will remove the entry from the history
// This cannot be undone, so make sure you have a backup of the Storage ruleset
let result = await deleteRuleset(firebaseApp, ruleset.name);
console.log(result);
// TODO: manage error states (like 429 on firebaserules.googleapis.com)
}
rulesCounter++;
} else {
console.log('...skipping Firestore ruleset...');
}
}
pageToken = rules.nextPageToken || null;
}
if (!pageToken) {
// finish the cycle
break;
}
// small pause to avoid hitting a query limit
console.log(`---- 10s pause to prevent hitting limits ----`);
sleep(10);
} // while
console.log(`PAGES: ${pageCounter}`);
console.log(`DELETED STORAGE RULESETS: ${rulesCounter - 1}`);
})();
{
"name": "rulesets",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"firebase-admin": "^8.7.0",
"sleep": "^6.1.0",
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment